繁体   English   中英

Javascript:填充数组之间的缺失值

[英]Javascript: fill missing values between arrays

我正在寻找一种高性能的方法来填充两个数组之间互斥的值。 此数据用于JS图表,该图表必须包含每个x值的条目。 一个例子可以更好地解释这个:

之前:

obj1 = [{x:1, y:1}, {x:3, y:2}];
obj2 = [{x:2, y:2}, {x:4, y:4}];

后:

obj1 = [{x:1, y:1}, {x: 2, y:0}, {x:3, y:2}, {x:4, y:0}];
obj2 = [{x:1, y:0}, {x: 2, y:2}, {x:3, y:0}, {x:4, y:4}];

我使用嵌套for循环来自己做这件事,但随着对象和条目数量的增加,墙壁时间变得无法接受。 在最终零填充到几千个条目的数据集中,墙壁时间超过10秒。

我已经看过一些JS库,比如jQuery和下划线,但是目前还不清楚它们是否具有更好的执行功能。

更新 :感谢所有回复。 我会尝试一下,并将表现最佳的一个作为答案。 关于x值的注释:它们不一定是单调增加的(obj1和2可以跳过x值,只要它们都这样做)。 x轴不一定是数字,也可以是日期。 希望一个或多个答案适合于此。

基本上创建所有值的哈希值,以及每个对象中所有值的哈希值。 然后使用'all'哈希中的哈希填充对象,该哈希在'individual'哈希中不存在

// hash of unique x values
var xValues = {};

// store each distinct x value
walk( obj1, 'obj1' );
walk( obj2, 'obj2' );

// fill each array with missing values
fill( obj1, 'obj1' );
fill( obj2, 'obj2' );

function walk( obj, nm ){
    xValues[ nm ] || ( xValues[ nm ] = {} );
    xValues.all   || ( xValues.all   = {} );

    for( var i=0, l=obj.length; i<l; i++ ){
        xValues[ nm ][ obj[ i ].x ] = 1;
        xValues.all  [ obj[ i ].x ] = 1;
    }
}

function fill( obj, nm ){
    for( var key in xValues.all ){
        if( !( key in xValues[ nm ] ) ){
            obj.push( { x : key, y : 0 } );
        }
    }
}

添加另一个答案,假设您的数据已预先排序。 如果它没有预先排序,请对其进行排序,这将起作用。 它具有内存使用量极少的优点,速度非常快,完成后您的数据将被排序:

var maxX = Math.max(
      obj1[ obj1.length-1 ].x
    , obj2[ obj2.length-1 ].x
);

fill( obj1, maxX );
fill( obj2, maxX );

function fill( obj, max ){
    for( var i=0; i<max; i++ ){
        if( !obj[i] || ( obj[i].x !== i+1 ) ){
            obj.splice( i, 0, { x:i+1, y:0 });
        }
    }
}

如何使用以下方法(使用伪代码)

1)将其转换为数组,其中x为索引。

var arr = [];
for each object in input_list
    arr[object.x] = object.y

2)循环上面的数组并用零填充undefined

arr2 = arr.map -> return (typeof value !== 'undefined') value : 0

3)将数组转换回对象

result = arr2.map -> return { x : index, y: value }

PS:您可以通过组合步骤2和3来进一步优化它以保存另一个循环。

这是另一种方法。 尽可能使用本机实现的方法来提高性能。

var obj1 = [{x:1, y:1}, {x:3, y:2}];
var obj2 = [{x:2, y:2}, {x:4, y:4}];

// get the x values from each array
var xGetter = function(i) { return i.x; };
var obj1xs = obj1.map(xGetter);
var obj2xs = obj2.map(xGetter);

// get the joined array
var joined = obj1.concat(obj2);

// get all x values
var xs = joined.map(xGetter);

// get the min and max values of x from both arrays combined
var min = Math.min.apply(null, xs), max = Math.max.apply(null, xs), i = min;

// fill the missing x values with zero y value
if(min < max) {
  while(i<=max) {
    if(obj1xs.indexOf(i) === -1) obj1.push({x: i, y: 0});
    if(obj2xs.indexOf(i) === -1) obj2.push({x: i, y: 0});
    i++;
  }
}

// sort the arrays
var mySorter = function(a, b) { return a.x - b.x; };
obj1 = obj1.sort(mySorter);
obj2 = obj2.sort(mySorter);

输出将是:

obj1 => [{"x":1, "y":1}, {"x":2, "y":0}, {"x":3, "y":2}, {"x":4, "y":0}]
obj2 => [{"x":1, "y":0}, {"x":2, "y":2}, {"x":3, "y":0}, {"x":4, "y":4}]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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