如何合并两个类似于下划线扩展方法的对象

时间:2013-12-02 03:56:18

标签: javascript arrays sorting date underscore.js

我有两个数组数组,格式化的日期为关键字,数字为相应的值。

第一个数组使用 moment.js 给我最后七天,并且所有值都设置为零。

第二个数组为我提供了一些有意义的统计数据,如果有的话,在过去一周内会有几天;在当前实例中,这只是返回任何数字的一天。

我想将第二个数组合并到第一个数组并保留优先级,即初始时间段数组值将使用第二个数组中的值重写,然后返回单个数组以用于制图等。

我尝试通过转换为对象并使用下划线扩展方法来完成此操作,但不保留排序,这很重要。

以下是当前代码:

            var length = 7,
                day = moment(),
                arr = [];

            while (length--) {
                arr.push([day.subtract('days', length).format('D MMM'), 0]);
            }

返回过去七天的数组数组,例如

[["26 Nov", 0], ["27 Nov", 0]]... 

然后我从我的数据库查询中得到以下内容:

[["26 Nov", 6]]

所以我希望最终结果是:

[["26 Nov", 6], ["27 Nov", 0]]...

2 个答案:

答案 0 :(得分:2)

使用原生脚本

for(var i=0; i < newArray.length; i++){
    var d=newArray[i][0];
    for( var j= 0; j < oldArray.length ; j++){
         if( oldArray[j][0] ===d){
            oldArray[j][1] = newArray[i][1];
         }
    }
}

答案 1 :(得分:1)

使用下划线/ lodash可以执行类似这样的操作,其中newArr是数据库查询中的数据。

merged= _.groupBy(_.union(arr, newArr),function(val){ return val[0]});
var out = _(merged).map(function(val, key) {
   return ([key,_(val).reduce(function(m,x) { return m + x[1]; }, 0)]);
});

merged是一个数组,其中所有重复日期(数组条目0)合并为一个条目,然后我们使用经典的map-reduce,reduce将所有值相加(数组条目1)。

http://jsfiddle.net/g9nuC/1/

旁注,对于您可能更喜欢的过去7天的数组:

arr.push([day.subtract('days', 1).format('D MMM'), 0]);

<强>性能

在这种情况下,来自@charliefl的解决方案比下划线(取决于浏览器)大约快100倍(并且lodash比下划线快2倍)。这是一个比较下划线,lodash和纯JS解决方案的jsperf:http://jsperf.com/underscore-vs-native-test-kd/2

显然,有两种方法可以混合使用这两种解决方案并获得不同的性能结果。我将其保留为纯粹的lodash /下划线解决方案,以显示一个端点并将性能结果与Charlie的纯JS解决方案进行比较。

更复杂的情况会改变性能平衡 - 任何人都可以创建自己的jsperf变体来探索它。