Javascript填充数组具有中间值

时间:2016-10-16 17:46:30

标签: javascript arrays multidimensional-array fill missing-data

我试图填充缺少中间数据的数组

我的数据输入是这样的

  

var data = [[5.23,7],[5.28,7],[5.32,8],[5.35,8]];

我想填充缺少值的数组,但我需要遵守这条规则:

  1. 2d数组的第1个值必须是下一个序列号,所以5.23 ...... 5.24 ...... 5.25 ......
  2. 2d数组的第2个值必须与i + 1中的元素相同 值
  3. 所以这种情况下的结果将是

      

    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]];

    这段代码很有用,但我不知道 如何投入循环 以及如何编写一个while循环,每次遍历数组的新长度

    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(数据);

    有什么想法吗?

3 个答案:

答案 0 :(得分:1)

Array.prototype.reduce()有时可以方便地扩展数组。可能你可以这样做;

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);

答案 1 :(得分:1)

这是另一个想法......我认为直接遍历序列号可能感觉更自然。

你的最终数组范围(在本例中)从5.23增加到5.35,递增0.01。这种方法使用for循环从5.23开始到5.35递增0.01。

关键点

  • 舍入:在x100中工作然后向下划分以避免浮点舍入问题。 我使用toFixed(2)舍入到接近百位,然后转换回一个数字(使用前导+运算符)。
  • 索引:识别5.23是零索引,每个索引递增1/100,您可以从数值计算索引,例如。 100*(5.31-5.23)等于8(因此5.31属于output[8])。
  • 第二个值:给定一个数值(例如5.31),只需找到数据数组中第一个具有较高第一个值的元素并使用其第二个值 - 这是一个你的要求的必然结果。由于5.31 <= 5.28为假,因此请勿使用7(来自[5.28,7])。由于5.31 <= 5.32为真,请使用8(来自[5.32,8])。

修改

我稍微提高了性能 - (1)初始化输出而不是修改数组大小,(2)以100的倍数工作,而不是从浮点到百分之一连续舍入。

我在一个较长的例子上运行了5000次迭代,平均而言,这些修改使得这种方法 3x 比Redu还要快(原来的速度慢了2倍)。

&#13;
&#13;
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
&#13;
&#13;
&#13;

答案 2 :(得分:0)

我建议这个解决方案:

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);