Merge two unordered objects with different keys but same value?

前端 未结 5 1953
谎友^
谎友^ 2021-01-28 02:05

Merge objects like obj1 and obj2 to get obj3 in javascript.

obj1 = [{fruit: \'watermelon\', sweetness: 3},{fruit: \'banana\', sweetness: 4},{fruit: \'apple\', sw         


        
相关标签:
5条回答
  • 2021-01-28 02:26

    Not a general solution but enough for your case:

    var obj1 = [{fruit: 'watermelon', sweetness: 3},{fruit: 'banana', sweetness: 4},{fruit: 'apple', sweetness: 5}]
    var obj2 = [{fruit_name: 'apple', color: 'red'},{fruit_name: 'banana', color:'yellow'},{fruit_name: 'watermelon', color:'green'}]
    
    var obj3 = obj2.map(o => Object.assign({}, o, {'sweetness': obj1.find(p => p.fruit === o.fruit_name).sweetness}))
    
    console.log(obj3)

    0 讨论(0)
  • 2021-01-28 02:29

    It's fairly simple to put together a generic function to merge two arrays of objects with a shared key. The easiest way to do it is to use a mapping based on an associate array, as follows. Note that you could use this routine to solve any problem of a similar type, but it definitely works with your data--see the JSFiddle linked at the end.

    (ETA: The shared key is added only once, with the name provided as key1; if you want the second key to wind up in the output, simply swap the pairs of arguments to the function.)

    obj1 = [{fruit: 'watermelon', sweetness: 3},{fruit: 'banana', sweetness: 4},{fruit: 'apple', sweetness: 5}];
    obj2 = [{fruit_name: 'apple', color: 'red'},{fruit_name: 'banana', color:'yellow'},{fruit_name: 'watermelon', color:'green'}];
    
    function mergeObjectArrays(array1, key1, array2, key2) {
      var map = []; // an associative array/hashtable
      var arrayValue, mapValue, propertyNames, propertyName, propertyValue;
    
      // 1. Loop over one array, populating the map by each object's specified key
        for(var x = 0; x < array1.length; x++) {
        array1Value = array1[x];
        map[array1Value[key1]] = array1Value;
        map.push(array1Value);
      }
    
      // 2. Loop over the other array, matching on the provided keys
      for(var x = 0; x < array2.length; x++) {
        arrayValue = array2[x];
        mapValue = map[arrayValue[key2]];
    
        if (typeof(mapValue) != 'undefined') { // add all missing non-keyed properties to the mapped/merged object
          propertyNames = Object.keys(arrayValue);
          for (var y = 0; y < propertyNames.length; y++) {
              propertyName = propertyNames[y];
              if (propertyName != key1 && propertyName != key2) { // .. as that shared value is already added
                propertyValue = arrayValue[propertyName];
                mapValue[propertyName] = propertyValue;
              }
          }      
        }
        else { // it's missing from the mapping, so at least add it though it will be missing array1 data
          map[arrayValue[key2]] = arrayValue;
          map.push(arrayValue);
        }
      }
    
      return map;
    }
    
    var mergedArrays = mergeObjectArrays(obj1, 'fruit', obj2, 'fruit_name');
    

    Here's a working sample.

    0 讨论(0)
  • 2021-01-28 02:30
    let obj1 = [{fruit: 'watermelon', sweetness: 3},{fruit: 'banana', sweetness: 4},{fruit: 'apple', sweetness: 5}];
    let obj2 = [{fruit_name: 'apple', color: 'red'},{fruit_name: 'banana', color:'yellow'},{fruit_name: 'watermelon', color:'green'}];
    
    function regulate(a) {
      return a.map(v => {
        if (v.fruit) {
            v.fruit_name = v.fruit;
            delete v.fruit;
         }
         return v;
      });
    }
    
    
    let a = [].concat(regulate(obj1), regulate(obj2));
    
    let merged = [];
    a.reduce((m, v) => {
      let f = m.filter(v2 => v2.fruit_name === v.fruit_name);
      if (f.length > 0) {
        Object.assign(f[0], v);
      } else {
        m.push(v);
      }
      return m;
    }, merged);
    
    console.log(merged);
    
    0 讨论(0)
  • 2021-01-28 02:44

    You can first create a hashtable by merging similar objects using #forEach and then extract the required array using a #map() function - see demo below:

    var obj1 = [{fruit: 'watermelon', sweetness: 3},{fruit: 'banana', sweetness: 4},{fruit: 'apple', sweetness: 5}],
      obj2 = [{fruit_name: 'apple', color: 'red'},{fruit_name: 'banana', color:'yellow'},{fruit_name: 'watermelon', color:'green'}], hash = {};
    
    // function to create a hashtable
    function classify(e) {
       if(hash[e.fruit] || hash[e.fruit_name]) {
         Object.keys(e).forEach(function(c){
            hash[e.fruit || e.fruit_name][c] = e[c];
         });
       } else {
         hash[e.fruit_name || e.fruit] = e;
       }
    }
    
    // add to hash
    obj1.forEach(classify);
    obj2.forEach(classify);
    
    // extract the result
    var obj3 = Object.keys(hash).map(function(e){
      delete hash[e]['fruit'];
      return hash[e];
    });
    
    console.log(obj3);
    .as-console-wrapper{top:0;max-height:100%!important;}

    0 讨论(0)
  • 2021-01-28 02:53

    Your data structure is incorrect. You can not save "'fruit: 'watermelon'" (key, value pair) in an array.

    It would give an error: Uncaught SyntaxError: Unexpected token :

    I am assuming what you are trying to do is:

    obj1 = [{fruit: 'watermelon', sweetness: 3},{fruit: 'banana', sweetness: 4},{fruit: 'apple', sweetness: 5}]
      obj2 = [{fruit_name: 'apple', color: 'red'},{fruit_name: 'banana', color:'yellow'},{fruit_name: 'watermelon', color:'green'}]
      obj3 = [];
      
    for (i = 0; i < obj1.length; i++) {
      for (j = 0; j < obj2.length; j++) {
        if (obj1[i].fruit === obj2[j].fruit_name) {
          var temp = {
            fruit_name: obj2[j].fruit_name,
            color: obj2[j].color,
            sweetness: obj1[i].sweetness
          }
          obj3.push(temp);
        }
      }
    }
    
    console.log(obj3);

    0 讨论(0)
提交回复
热议问题