2015-08-28 63 views
0

我有合并2个阵列像这样:我需要合并2阵列,一起大概相同的数据

数组1(数据来自API):

{ '0': 
    { userid: 'kdkds', 
    name: 'Stephan, 
    email: '[email protected]' , 
    tag: '2015-04-02', 
    schicht_id: 'pikett', 
    schicht_name: 'Pikett', 
    beschreibung: null, 
    administrativ: '0' }, 
    '1': 
    { userid: 'kdkds', 
    name: 'Stephan', 
    email: '[email protected]' , 
    tag: '2015-04-03', 
    schicht_id: 'pikett', 
    schicht_name: 'Pikett', 
    beschreibung: null, 
    administrativ: '0' } }; 

数组2(从DB数据):

{ '0': 
    { userid: 'kdkds', 
    del: 'true', 
    art: 'Pikett' , 
    datum: '2015-04-02'}, 
    '1': 
    { userid: 'kdkds', 
    del: 'false', 
    art: 'Pikett', 
    datum: '2015-04-03'} 

}; 

我需要在端什么是第一阵列从与匹配的用户ID和日期的第二阵列的附加数据:

{ '0': 
     { userid: 'kdkds', 
     name: 'Stephan, 
     email: '[email protected]' , 
     tag: '2015-04-02', 
     schicht_id: 'pikett', 
     schicht_name: 'Pikett', 
     beschreibung: null, 
     administrativ: '0', 
     del: 'true'}, 
     '1': 
     { userid: 'kdkds', 
     name: 'Stephan', 
     email: '[email protected]' , 
     tag: '2015-04-03', 
     schicht_id: 'pikett', 
     schicht_name: 'Pikett', 
     beschreibung: null, 
     administrativ: '0', 
     del: 'false' } }; 

如果第二个数组中不存在第二个数组中的条目,则它也必须位于最终数组中。

我使用nodejs,那么最简单的方法是什么?

+3

只是说明:这里没有数组,只是带有键的对象。 – petr

+2

这些是**对象**而不是**阵列**。告诉我们你试过了什么? – Mritunjay

+0

除了它们实际上并不是数组。 Array1和Array2总是一样的长度? – Sphaso

回答

0

目前我的解决办法是:

function merge() { 
     var dst = {} 
      ,src 
      ,p 
      ,args = [].splice.call(arguments, 0) 
     ; 

     while (args.length > 0) { 
      src = args.splice(0, 1)[0]; 
      if (toString.call(src) == '[object Object]') { 
       for (p in src) { 
        if (src.hasOwnProperty(p)) { 
         if (toString.call(src[p]) == '[object Object]') { 
          dst[p] = merge(dst[p] || {}, src[p]); 
         } else { 
          dst[p] = src[p]; 
         } 
        } 
       } 
      } 
     } 

     return dst; 
    } 

但是我必须做一些测试

+0

使用'typeof'而不是toString来确定类型... –

0

这是很容易的。只是循环通过对象。

var result = Array1 
for(var i in Array2){ 
    if(result[i]){ 
    for(var p in Array2[i]){ 
     result[i][p] = Array2[i][p] 
    } 
    } 
    else {result[i] = Array2[i]} 
} 

警告:Array1被修改并引用了Array2。

0

考虑到你不想合并数组,但对象,你可能想要做这样的事情:

var mergeFunction = function(a1, a2) { 
    // Settings 
    var propertyToCompareArray1 = ['userid', 'tag']; 
    var propertyToCompareArray2 = ['userid', 'datum']; 

    for(var i = 0; i<Object.keys(a2).length;i++) 
    { 
     var itemA2 = Object.keys(a2)[i]; 
     for(var j = 0; j<Object.keys(a2[itemA2]).length;j++) { 
     var currentProp = Object.keys(a2[itemA2])[j]; 
     var shouldSkip = false; 
     for(var l=0;l<propertyToCompareArray2.length;l++) { 
      if(currentProp === propertyToCompareArray2[l]) 
      shouldSkip = true; 
     } 

      if(shouldSkip) 
       continue; 

     for(var k=0; k<Object.keys(a1).length; k++) { 
      var doesMatch = true; 
      for(var l=0;l<propertyToCompareArray1.length;l++) { 
       if(a1[Object.keys(a1)[k]][propertyToCompareArray1[l]] === a2[itemA2][propertyToCompareArray2[l]]) 
       { 
        doesMatch = false; 
       } 
      } 
      if(doesMatch) 
      { 
       a1[itemA2][currentProp] = a2[itemA2][currentProp]; 
       continue; 
      } 
     } 
     } 
    } 
    return a1; 
}; 

然后运行:var res = mergeFunction(obj1, obj2);

其结果将是:

{ 
    '0': 
    { 
     administrativ: "0", 
     art: "Pikett", 
     beschreibung: null, 
     datum: "2015-04-02", 
     del: "true", 
     email: "[email protected]", 
     name: "Stephan", 
     schicht_id: "pikett", 
     schicht_name: "Pikett", 
     tag: "2015-04-02", 
     userid: "kdkds" 
    }, 
    '1': 
    { 
     administrativ: "0", 
     art: "Pikett", 
     beschreibung: null, 
     datum: "2015-04-03", 
     del: "false", 
     email: "[email protected]", 
     name: "Stephan", 
     schicht_id: "pikett", 
     schicht_name: "Pikett", 
     tag: "2015-04-03", 
     userid: "kdkds" 
} 

编辑:

此代码的工作,如果你使用你的问题描述的对象,如果你与真正的数组像这样的工作:

var obj1 = [ 
{ 
    userid: 'kdkds', 
    name: 'Stephan', 
    email: '[email protected]' , 
    tag: '2015-04-02', 
    schicht_id: 'pikett', 
    schicht_name: 'Pikett', 
    beschreibung: null, 
    administrativ: '0' 
}, 
{ 
    userid: 'kdkds', 
    name: 'Stephan', 
    email: '[email protected]' , 
    tag: '2015-04-03', 
    schicht_id: 'pikett', 
    schicht_name: 'Pikett', 
    beschreibung: null, 
    administrativ: '0' 
} 
]; 

和:

var obj2= [ 
    { 
    userid: 'kdkds', 
    del: 'true', 
    art: 'Pikett' , 
    datum: '2015-04-02' 
    }, 
    { 
    userid: 'kdkds', 
    del: 'false', 
    art: 'Pikett', 
    datum: '2015-04-03' 
} 
]; 

编辑2:

你可以试试这里:http://jsfiddle.net/cef61yo7/4/

0

你可以很容易地使用下划线来做到这一点,但如果你想纯JavaScript执行,你可以尝试其他的解决方案。这只是简短的解决方案。

如果你的对象的按键酷似一个数组的索引,你可以将其转换为数组,像这样:

obj1.length = _.size(obj1); 

var newArr = []; 

newArr = Array.prototype.map.call(obj1, function(el, index, arr){ 
    return _.extend(el, obj2[index]) 
}); 

新的阵列将包含合并后的结果作为数组。如果合并对象中有公共属性,则_.merge将覆盖第一个和第二个。但正如我所说,这是使用下划线的解决方案。

的文档
underscore extend
underscore size

编辑1 这种方法只适用,如果你的对象的键对应于数组的索引。就像你的问题一样。

0

在ES6:

Array1 . forEach((elt, idx) => Object.assign(elt, Array2[idx])); 

这会修改数组1。创建一个新的阵列:

Array1. map((elt, idx) => Object.assign({}, elt, Array2[idx])); 

这假设输入是实际的数组。

您可以使用babel-node运行此操作。随着node --harmony你需要为Object.assign.

0

提供一个垫片一个简单的和可重复使用的方式来实现这一目标:

function merge(a1, a2, doMerge) { 
    for(var item1 in a1) 
    { 
     for(var item2 in a2){ 
      if(doMerge(item1, item2)){ 
       for(var prop in item2){ 
       item1[prop] = item2[prop]; 
       } 
      }; 
     } 
    } 
    return a1; 
}; 

然后你可以使用它像这样:

var res = merge(obj1, obj2, function(item1, item2){ 
    return item1.userid === item2.userid && item1.tag === item2.datum; 
}); 

工作小提琴: http://jsfiddle.net/cef61yo7/5/