JavaScript merging objects by id

前端 未结 16 1601
没有蜡笔的小新
没有蜡笔的小新 2020-11-22 09:43

What\'s the correct way to merge two arrays in Javascript?

I\'ve got two arrays (for example):

var a1 = [{ id : 1, name : \"test\"}, { id : 2, name :         


        
相关标签:
16条回答
  • 2020-11-22 10:32

    None of them worked for me. I wrote own:

    const formatteddata=data.reduce((a1,a2)=>{
    
    for (let t=0; t<a1.length; t++)
        {var id1=a1[t].id
                for (let tt=0; tt<a2.length; tt++)
                    {var id2=a2[tt].id
                        if(id1==date2)
                          {a1[t]={...a1[t],...a2[tt]}}
                    }
        }
    return a1
    
    })
    

    works with any amount of arrays of objects in arrays, with varying length and not always coinsciding dates

    0 讨论(0)
  • 2020-11-22 10:33

    Short ES6 solution

    const a3 = a1.map(t1 => ({...t1, ...a2.find(t2 => t2.id === t1.id)}))
    
    0 讨论(0)
  • 2020-11-22 10:35

    The lodash implementaiton:

    var merged = _.map(a1, function(item) {
        return _.assign(item, _.find(a2, ['id', item.id]));
    });
    

    The result:

    [  
       {  
          "id":1,
          "name":"test",
          "count":"1"
       },
       {  
          "id":2,
          "name":"test2",
          "count":"2"
       }
    ]
    
    0 讨论(0)
  • 2020-11-22 10:36
    const a3 = a1.map(it1 => {
       it1.test = a2.find(it2 => it2.id === it1.id).test
       return it1
     })
    
    0 讨论(0)
  • 2020-11-22 10:40

    Assuming IDs are strings and the order does not matter, you can

    1. Create a hash table.
    2. Iterate both arrays and store the data in the hash table, indexed by the ID. If there already is some data with that ID, update it with Object.assign (ES6, can be polyfilled).
    3. Get an array with the values of the hash map.
    var hash = Object.create(null);
    a1.concat(a2).forEach(function(obj) {
        hash[obj.id] = Object.assign(hash[obj.id] || {}, obj);
    });
    var a3 = Object.keys(hash).map(function(key) {
        return hash[key];
    });
    

    In ECMAScript6, if the IDs are not necessarily strings, you can use Map:

    var hash = new Map();
    a1.concat(a2).forEach(function(obj) {
        hash.set(obj.id, Object.assign(hash.get(obj.id) || {}, obj))
    });
    var a3 = Array.from(hash.values());
    
    0 讨论(0)
  • 2020-11-22 10:42

    A working TypeScript version:

    export default class Merge {
      static byKey(a1: any[], a2: any[], key: string) {
        const res = a1.concat(a2).reduce((acc, x) => {
          acc[x[key]] = Object.assign(acc[x[key]] || {}, x);
          return acc;
        }, {});
    
        return Object.entries(res).map(pair => {
          const [, value] = pair;
          return value;
        });
      }
    }
    
    test("Merge", async () => {
      const a1 = [{ id: "1", value: "1" }, { id: "2", value: "2" }];
      const a2 = [{ id: "2", value: "3" }];
    
      expect(Merge.byKey(a1, a2, "id")).toStrictEqual([
        {
          id: "1",
          value: "1"
        },
        { id: "2", value: "3" }
      ]);
    });
    
    
    0 讨论(0)
提交回复
热议问题