簡體   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