简体   繁体   English

带有中间值的Javascript填充数组

[英]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: 我想用缺少的值填充数组,但我需要遵守以下规则:

  1. The 1st value on 2d array must be the next sequence number, so 5.23 ... 5.24 ... 5.25 ... 2d数组上的第一个值必须是下一个序列号,因此5.23 ... 5.24 ... 5.25 ...
  2. The 2nd value on 2d array must be the same element from the i+1 value 2d数组上的第二个值必须与i + 1值相同

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 关键点

  • Rounding : Work in x100 then divide back down to avoid floating point rounding issues. 舍入 :在x100中工作,然后再向下划分以避免浮点舍入问题。 I round to the neared hundredth using toFixed(2) and then converting back to a number (with leading + operator). 我使用toFixed(2)舍入到接近百分之一,然后转换回数字(使用前导 +运算符)。
  • Indexing : Recognizing 5.23 is the zero index with each index incrementing 1/100, you can calculate index from numerical values, ex. 索引编制:识别5.23是零索引,每个索引递增1/100,您可以从数值(例如)计算索引。 100*(5.31-5.23) equals 8 (so 5.31 belongs in output[8] ). 100*(5.31-5.23)等于8 (因此5.31属于output[8] )。
  • 2nd values : given a numerical value (ex. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM