[英]Javascript fill array with intermediate value
I'm trying to fill an array with missing intermediate data 我正在尝试使用缺少的中间数据填充数组
My data input is like this 我的数据输入是这样的
var data = [[5.23,7],[5.28,7],[5.32,8],[5.35,8]]; var data = [[5.23,7],[5.28,7],[5.32,8],[5.35,8]];
I wanna fill the array with missing value but I need to respect this rule: 我想用缺少的值填充数组,但我需要遵守以下规则:
So the results in this case would be 所以在这种情况下的结果是
var data = [[5.23,7],[5.24,7],[5.25,7],[5.26,7],[5.27,7],[5.28,7],[5.29,8],[5.30,8],[5.31,8],[5.32,8],[5.33,8],[5.34,8],[5.35,8]]; var data = [[5.23,7],[5.24,7],[5.25,7],[5.26,7],[5.27,7],[5.28,7],[5.29,8],[5.30,8 ],[5.31,8],[5.32,8],[5.33,8],[5.34,8],[5.35,8]];
This little piece of code works, but I don't know how to put in loop and how to write a while loop that pass every time the new length of the array 这小段代码有效,但是我不知道如何放入循环以及如何编写每次新的数组长度都经过的while循环
var data = [[5.23,7],[5.28,7],[5.32,8],[5.35,8]]; var data = [[5.23,7],[5.28,7],[5.32,8],[5.35,8]];
if (data[1][0]-data[0][0] > 0.01) {
data.push([data[0][0]+0.01,data[1][1]]);
data.sort(function (a, b) { return a[0] - b[0]; });
} else {
check the next element
}
console.log(data); console.log(data);
Any idea? 任何想法?
Array.prototype.reduce()
is sometimes handy to extend the array. Array.prototype.reduce()
有时很方便扩展数组。 May be you can do as follows; 可能您可以执行以下操作;
var data = [[5.23,7],[5.28,7],[5.32,8],[5.35,8]], newData = data.reduce((p,c,i,a) => i ? p.concat(Array(Math.round(c[0]*100 - a[i-1][0]*100)).fill() .map((_,j) => [Number((a[i-1][0]+(j+1)/100).toFixed(2)),c[1]])) : [c],[]); console.log(newData); var data = [[1.01,3],[1.04,4],[1.09,5],[1.10,6],[1.15,7]], newData = data.reduce((p,c,i,a) => i ? p.concat(Array(Math.round(c[0]*100 - a[i-1][0]*100)).fill() .map((_,j) => [Number((a[i-1][0]+(j+1)/100).toFixed(2)),c[1]])) : [c],[]); console.log(newData);
Here's another idea... I thought it might feel more natural to loop through the sequence numbers directly. 这是另一个想法...我认为直接遍历序列号可能会更自然。
Your final array will range (in this example) from 5.23 to 5.35 incrementing by 0.01. 您的最终数组(在此示例中)的范围为5.23至5.35,以0.01为增量。 This approach uses a for loop starting going from 5.23 to 5.35 incrementing by 0.01. 此方法使用for循环,从5.23到5.35递增0.01。
key points 关键点
+
operator).
+
运算符)。
100*(5.31-5.23)
equals 8
(so 5.31
belongs in output[8]
). 100*(5.31-5.23)
等于8
(因此5.31
属于output[8]
)。 5.31
), just find the first element in the data array with a higher 1st value and use its 2nd value - this is a corollary of your requirement. 第二个值 :给定一个数值(例如5.31
),只需在数据数组中找到具有较高第一个值的第一个元素并使用其第二个值-这是您要求的必然结果。 Because 5.31 <= 5.28
is false, don't use 7
(from [5.28,7]
). 因为5.31 <= 5.28
为假,所以不要使用7
(来自[5.28,7]
)。 Because 5.31 <= 5.32
is true, use 8
(from [5.32,8]
). 因为5.31 <= 5.32
为true,所以使用8
(来自[5.32,8]
)。 EDIT 编辑
I improved the performance a bit - (1) initialize output instead of modifying array size, (2) work in multiples of 100 instead of continuously rounding from floating point to hundredths. 我提高了性能-(1)初始化输出而不是修改数组大小,(2)以100的倍数工作,而不是从浮点数连续舍入到百分之一。
I ran 5000 iterations on a longer example and, on average, these modifications make this approach 3x faster than Redu's (where the original was 2x slower). 我在一个较长的示例上运行了5000次迭代,平均而言,这些修改使此方法比Redu的方法快3倍 (原始方法要慢2 倍 )。
var data = [[5.23,7],[5.28,7],[5.32,8],[5.35,8]]; var output = Array((data[data.length-1][0]-data[0][0]).toFixed(2)*100+1) function getIndex(value){ return (value-data[0][0]*100) } for( var i = 100*data[0][0]; i <= 100*data[data.length-1][0]; i++ ){ output[getIndex(i)] = [i/100, data.find( d => i <= 100*d[0] )[1]] } //console.log(output) // Performance comparison function option1(data){ let t = performance.now() var output = Array((data[data.length-1][0]-data[0][0]).toFixed(2)*100+1) function getIndex(value){ return (value-data[0][0]*100) } for( var i = 100*data[0][0]; i <= 100*data[data.length-1][0]; i++ ){ output[getIndex(i)] = [i/100, data.find( d => i <= 100*d[0] )[1]] } return performance.now()-t } function option2(data){ let t = performance.now() newData = data.reduce((p,c,i,a) => i ? p.concat(Array(Math.round(c[0]*100 - a[i-1][0]*100)).fill() .map((_,j) => [Number((a[i-1][0]+(j+1)/100).toFixed(2)),c[1]])) : [c],[]); return performance.now()-t } var testdata = [[1.13,4],[2.05,6],[5.23,7],[5.28,7],[5.32,8],[5.35,8],[8.91,9],[10.31,9]]; var nTrials = 10000; for(var trial=0, t1=0; trial<=nTrials; trial++) t1 += option1(testdata) for(var trial=0, t2=0; trial<=nTrials; trial++) t2 += option2(testdata) console.log(t1/nTrials) // ~0.4 ms console.log(t2/nTrials) // ~0.55 ms
I propose this solution : 我提出这个解决方案:
var data = [[5.23,7],[5.28,7],[5.32,8],[5.35,8]];
var res = [];
data.forEach((item, index, arr) => {
res.push(item);
var temp = item[0];
while (arr[index+1] && arr[index+1][0]-temp > 0.01){
temp += 0.01;
res.push([temp, arr[index+1][1]]);
}
});
console.log(res);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.