为了账号安全,请及时绑定邮箱和手机立即绑定

Javascript从数组中的高点组中挑选出峰值数

Javascript从数组中的高点组中挑选出峰值数

开心每一天1111 2021-06-30 05:18:51
很难用标题来描述它,但从这里的描述和代码中应该很清楚。我试图从一组峰值中挑选出数组中的最高数字,然后进入下一组并从下一组高点中获取下一个峰值数。所以例如在这个数组中:const arr = [939, 1301, 253, 1380, 1037, 2279, 2462, 2193, 2121, 1424, 506, 2411, 2456, 2295, 915, 1276, 1532, 1359, 985, 2182, 2407, 2103, 2392, 2294, 765, 1195, 1537, 1409, 858, 1971, 2214, 1311, 1326, 1383, 1231, 1141]我想2462从大约 的第一组峰值中1037, 2279, 2462, 2193挑选出来,然后继续2456从大约 的下一组中挑选出来506, 2411, 2456, 2295, 915。这些组的位置未知,只需找到它们并从每个组中选择一个最高的数字即可。这是我目前拥有的功能,但它不能 100% 工作并且不适用于某些数组。let currHigh = 0, store = [], limit = 2100;for (let s = 0; s < arr.length; s++) {    if (arr[s] > limit && currHigh === 0) {        currHigh = arr[s]    } else if (arr[s] > limit && arr[s] > currHigh) {        currHigh = arr[s];    } else if (arr[s] < currHigh) {        if (arr[s] < limit) {            store.push(currHigh); currHigh = 0;        }    }}console.log(store)高点总是非常相似(2000+),数字组的位置相似但不一样,所以我不能真正依赖它。所以第一个数组和预期/期望的输出是:const arr = [939, 1301, 253, 1380, 1037, 2279, 2462, 2193, 2121, 1424, 506, 2411, 2456, 2295, 915, 1276, 1532, 1359, 985, 2182, 2407, 2103, 2392, 2294, 765, 1195, 1537, 1409, 858, 1971, 2214, 1311, 1326, 1383, 1231, 1141]Outputted Peaks: [2462, 2456, 2407, 2294, 2214]另一个具有预期/所需输出的示例数组:const arr =  [1365, 1324, 1013, 1220, 1259, 2204, 2212, 1938, 1882, 1545, 1236, 2090, 2614, 1949, 1307, 1628, 1780, 1263, 1184, 2184, 1411, 1306, 2010, 2057, 1339, 1624, 2480, 2575, 2425, 2617, 2479, 1929, 1805, 1869, 1341, 1104, 2195, 1661, 1174, 1447, 1761, 1362, 1430]Outputted Peaks: [2212, 2614, 2184, 2480, 2617, 2195]编辑:为了避免混淆,想象一下,如果您要获取给定数组中的值并将它们绘制在图形上,图形中会有几个相互隔开的峰值。我需要一个函数来获得这些峰值。查找组只是查找峰值的一种方法。它们就像迷你山。因此,例如,您不会希望获得位于“山的一侧”的高数字。编辑:附加图像来解释峰值。紧挨着另一个高数的高数不是峰,只有一小组相邻数中的最高数才是峰。 最终编辑:此图最好地说明了它,因为很难想象仅查看数组的图:https://jsbin.com/nicuciquru/1/edit?js,output所以我在这里需要的是[1301, 1380, 2462, 2456, 1532, 2407, 2492, 1537, 2214, 1383]你可以在图表上看到的峰值。然后从那里可以使用阈值轻松过滤这些峰值,例如消除低于 2000 的任何峰值。
查看完整描述

3 回答

?
慕标琳琳

TA贡献1830条经验 获得超9个赞

这是一个查找样本数组中所有峰值的函数:


    const chart = [939, 1301, 253, 1380, 1037, 2279, 2462, 2193, 2121, 1424, 506, 2411, 2456, 2295, 915, 1276, 1532, 1359, 985, 2182, 2407, 2103, 2392, 2294, 765, 1195, 1537, 1409, 858, 1971, 2214, 1311, 1326, 1383, 1231, 1141]


    const findPeaks = chart => chart.reduce((agg, current, i) => {

        const prev = chart[i - 1];

        const next = chart[i + 1];


        return current > prev && current > next ? [...agg, current] : agg;

    }, []);


    const peaks = findPeaks(chart);


    console.log('peaks', peaks);

这记录: [1301, 1380, 2462, 2456, 1532, 2407, 2392, 1537, 2214, 1383]


这与您的问题的预期输出不匹配,但它确实对“峰值是什么”给出了准确的答案。


在这种情况下,“峰值”被定义为任何前任和后继都低于自身的数字。即 [1, 100, 1] 给出 100。 [1, 2, 3, 100, 3, 2, 100, 1] 给出 [100, 100]


更新


根据您的反馈,这里有一个函数,它需要一个峰的每边距离为 2 。结果仍然与您的问题不同,但这符合新表达的标准:


const findPeaks = chart => chart.reduce((agg, current, i) => {

        const twoBack = chart[i - 2];

        const prev = chart[i - 1];

        const next = chart[i + 1];

        const twoForward = chart[i + 2];


        return (twoBack < prev && prev < current) && (current > next  && next > twoForward ) 

        ? [...agg, current] 

        : agg;

    }, []);

对于上述输入,这会产生:


[2462, 2456, 1532, 1537, 1383]


更新 2


这是找到所有峰值、计算出中值并返回大于中值的所有峰值的代码版本。这是与您在问题中要求的最接近的结果:


const findPeaks = chart => {


    const peaks = chart.reduce((agg, current, i) => {

    const twoBack = chart[i - 2];

    const prev = chart[i - 1];

    const next = chart[i + 1];

    const twoForward = chart[i + 2];


    return (prev < current) && (current > next) 

    ? [...agg, current] 

    : agg;

    }, []);


    const mean = peaks.reduce((a, b) => a + b) / peaks.length;


    return peaks.filter(peak => peak > mean);

}

这个的输出是:


[2462, 2456, 2407, 2392, 2214]


查看完整回答
反对 回复 2021-07-01
?
HUH函数

TA贡献1836条经验 获得超4个赞

没有更精确地定义所需的输出(例如,什么被认为是一个组?),这是一个简单的算法:


1) 将数组拆分为“低”和“高”序列。


例如[1, 10000, 100, 101, 20000, 20050, 30, 10, 2]=> [1], [10000], [100, 101], [20000, 20050], [30, 10, 2]。

2) 返回每个高序列的最大值。


let peaks = arr => {

    let isHigh = a => a >= 2000;

    let isLow = a => !isHigh(a);


    let groups = [];

    while (arr.length && arr.some(isHigh)) {

        arr.splice(0, arr.findIndex(isHigh));

        groups.push(arr.splice(0, arr.findIndex(isLow)));

    }


    return groups.map(group => Math.max(...group));

};



const arr = [939, 1301, 253, 1380, 1037, 2279, 2462, 2193, 2121, 1424, 506, 2411, 2456, 2295, 915, 1276, 1532, 1359, 985, 2182, 2407, 2103, 2392, 2294, 765, 1195, 1537, 1409, 858, 1971, 2214, 1311, 1326, 1383, 1231, 1141];

console.log(peaks(arr));


const arr2 = [1365, 1324, 1013, 1220, 1259, 2204, 2212, 1938, 1882, 1545, 1236, 2090, 2614, 1949, 1307, 1628, 1780, 1263, 1184, 2184, 1411, 1306, 2010, 2057, 1339, 1624, 2480, 2575, 2425, 2617, 2479, 1929, 1805, 1869, 1341, 1104, 2195, 1661, 1174, 1447, 1761, 1362, 1430];

console.log(peaks(arr2));


查看完整回答
反对 回复 2021-07-01
?
慕容708150

TA贡献1831条经验 获得超4个赞

为什么不保持简单?


var arr = [1,6,4,3,9,11];


var peaks = arr.sort((a, b) => a - b).reverse();

输出为:[11, 9, 6, 4, 3, 1]


然后:


var top5 = peaks.slice(0,5);

结果是:[11, 9, 6, 4, 3]


或者你的数学的整个代码:


const peaks1 = [939, 1301, 253, 1380, 1037, 2279, 2462, 2193, 2121, 1424, 506, 2411, 2456, 2295, 915, 1276, 1532, 1359, 985, 2182, 2407, 2103, 2392, 2294, 765, 1195, 1537, 1409, 858, 1971, 2214, 1311, 1326, 1383, 1231, 1141];

const peaks2 =  [1365, 1324, 1013, 1220, 1259, 2204, 2212, 1938, 1882, 1545, 1236, 2090, 2614, 1949, 1307, 1628, 1780, 1263, 1184, 2184, 1411, 1306, 2010, 2057, 1339, 1624, 2480, 2575, 2425, 2617, 2479, 1929, 1805, 1869, 1341, 1104, 2195, 1661, 1174, 1447, 1761, 1362, 1430];

const peaks = [peaks1, peaks2];

function getPeaks(arr){

    let peaks = [];

    for(let i=0;i<arr.length;i++){

        let currPeak = arr[i].sort((a, b) => a - b).reverse().slice(0,1)[0];

        peaks.push(currPeak);

    }

    return peaks.sort((a, b) => a - b).reverse();

}

let result = getPeaks(peaks);

结果应该是:[2617, 2462]


查看完整回答
反对 回复 2021-07-01
  • 3 回答
  • 0 关注
  • 307 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信