我有以下图表,它是数组[2,8,12,5,3,...]
的表示。 X轴以秒为单位。当y值保持0超过2秒时,我想将此数组分成多个部分。因此,此示例中的数组将分为3个部分:x = 0 to 8
,x = 8 to 13
和x = 13 to 20
,因为y从8到13保持= 0超过2秒。实际上,此数组可能是巨大。在纯javascript(或者如果需要lodash / underscore)中执行此操作的最快方法是什么?目前我循环遍历此数组以标记2秒停止时间。有没有更好的方法呢?
答案 0 :(得分:2)
您将始终需要查看数组的值,因此您将无法获得比O(n)解决方案更进一步的功能。效率最高的可能是使用包含您在某一点通过的零量的变量来运行数组。
下面的功能是一个匆忙制作的实现。我还使用了一个变量来存储以前的索引。这也可以从split数组中计算出来,但是如果你真的在谈论大数组的话,这将是相当低效的。
function splitArray(array, treshold) {
var zeros = 0,
previousIdx = 0,
splitArrays = [];
array.forEach(function(point, idx) {
if (point === 0) {
zeros++;
if (zeros == treshold && previousIdx != idx - treshold + 1) {
splitArrays.push(array.slice(previousIdx, idx - treshold + 1));
previousIdx = idx - treshold + 1;
}
} else if (zeros >= treshold) {
splitArrays.push(array.slice(previousIdx, idx));
previousIdx = idx;
zeros = 0;
}
});
if (previousIdx != array.length -1) {
splitArrays.push(array.slice(previousIdx));
}
return splitArrays;
}
我创建了一个JSFiddle,它使用一些测试数据显示了这个函数:https://jsfiddle.net/Glodenox/La8m3du4/2/
我不怀疑这段代码仍然可以改进。
如果您只想获取各个部分的索引而不是包含单独数组中所有数据的数组,则可以使用array.slice(a, b)
替换三个[a, b-1]
语句。
答案 1 :(得分:2)
您可以使用带有一个循环的迭代方法,同时检查预期的零值并确定是否达到阈值。然后删除最后一个间隔并将长度附加到数组之前。
此提案产生
threshold = 2
:
[ [ 1, 7], [ 8, 13], [14, 20] ]
threshold = 7
:
[ [ 1, 20] ]
var y = [2, 8, 12, 5, 3, 2, 0, 0, 3, 4, 8, 10, 8, 10],
x = [1, 2, 4, 5, 6, 7, 8, 13, 14, 15, 16, 18, 19, 20],
threshold = 2,
isZero = false;
result = [];
y.forEach(function (a, i) {
var last = result[result.length - 1];
if ((a === 0) !== isZero) {
if (last) {
last[1] = x[i];
}
return;
}
isZero = !isZero;
if (last && isZero && x[i] - last[0] < threshold) {
result.pop();
if (result[result.length - 1]) {
result[result.length - 1][1] = x[i];
}
return;
}
result.push([x[i]]);
});
console.log(result);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;