最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Merge duplicate objects in single array using lodash - Stack Overflow

programmeradmin0浏览0评论

I'm trying to merge duplicate objects in a json array I received.

The array looks like this:

{
  modules: [{
    "name": "Weazel",
    "otherprop": ["a", "b"]
  }, {
    "name": "weazel",
    "otherprop": ["c", "b"]
  }]
}

For some reason I can't figure out how to merge the duplicates.

I have tried doing it by first mapping all the names to lowercase and then use unique, but that removes the values for otherprops.

let result = _.map(json.modules, mod => { mod.name = mod.name.tolower(); return mod; });
result = _.unique(result, 'name');

Is there anyone who knows how I can tackle my issue using lodash?

I'm trying to merge duplicate objects in a json array I received.

The array looks like this:

{
  modules: [{
    "name": "Weazel",
    "otherprop": ["a", "b"]
  }, {
    "name": "weazel",
    "otherprop": ["c", "b"]
  }]
}

For some reason I can't figure out how to merge the duplicates.

I have tried doing it by first mapping all the names to lowercase and then use unique, but that removes the values for otherprops.

let result = _.map(json.modules, mod => { mod.name = mod.name.tolower(); return mod; });
result = _.unique(result, 'name');

Is there anyone who knows how I can tackle my issue using lodash?

Share Improve this question edited Nov 8, 2016 at 11:30 Liam 29.8k28 gold badges139 silver badges203 bronze badges asked Nov 8, 2016 at 11:28 MarcoMarco 5,1096 gold badges39 silver badges77 bronze badges 1
  • It's not really clear what otherprop should be after your merge. ['a','b','c']? ['a','b','c','b']? – Andrey Commented Nov 8, 2016 at 12:00
Add a ment  | 

4 Answers 4

Reset to default 3
var result = _.uniq(json.modules, function(item, key, a) { 
        return item.a;
    });

//Result : [{"name":"Weazel","otherprop":["a","b"]}]

You can achieve that using lodash's _.groupBy() with _.map() and _.mergeWith():

function mergeByName(arr) {
  return _(arr)
    .groupBy(function(item) { // group the items using the lower case
      return item.name.toLowerCase();
    })
    .map(function(group) { // map each group
      return _.mergeWith.apply(_, [{}].concat(group, function(obj, src) { // merge all items, and if a property is an array concat the content
        if (Array.isArray(obj)) {
          return obj.concat(src);
        }
      }))
    })
    .values() // get the values from the groupBy object
    .value();
}


var arr = {
  modules: [{
    "name": "Weazel",
    "otherprop": ["a", "b"]
  }, {
    "name": "weazel",
    "otherprop": ["c", "b"]
  }]
}

var result = mergeByName(arr.modules);

console.log(result);
<script src="https://cdnjs.cloudflare./ajax/libs/lodash.js/4.16.6/lodash.min.js"></script>

Pure JS ES6 you might do as follows;

var modules = [{      "name": "Weazel",
                 "otherprop": ["a", "b"]
               },
               {      "name": "weazel",
                 "otherprop": ["c", "b"]
               },
               {      "name": "trix",
                 "otherprop": ["y", "z"]
               },
               {      "name": "trix",
                 "otherprop": ["x", "y"]
               }],
     result = [...modules.reduce(function(m,o){
                                   var name = o.name.toLowerCase();
                                        obj = m.get(name);
                                   return obj ? m.set(name,{     name: name,
                                                            otherprop: [...new Set(obj.otherprop.concat(o.otherprop))]
                                                           })
                                              : m.set(name,o);
                                 },new Map())
                         .values()];
console.log(result);

I'm not sure about lodash or underscore, but for reference: a vanilla js solution. Might be nice to use a starting point and convert parts of it to their library-equivalents.

var json = {
  modules: [{
    "name": "Weazel",
    "otherprop": ["a", "b"]
  }, {
    "name": "weazel",
    "otherprop": ["c", "b"]
  }]
};

// The merge logic
var mergeModules = function(m1, m2) {
  // For example:
  return {
    name: m1.name,
    otherprop: (m2 ? m2.otherprop : [])
      .concat(m1.otherprop)
      .sort() // Note: add some sort of `uniques` method here as well
  };
};

// The 'normalize' key logic
var getModuleKey = function(mod) {
    return mod.name.toLowerCase();
};

// Create an object with a merged module for each unique key
var uniques = json.modules.reduce(function(map, current) {
  var key = getModuleKey(current); 
  map[key] = mergeModules(current, map[key]);
  return map;
}, {});

// Transform uniqes object ({ weasel: {}}) back to array: [{}]
var mergedArr = Object.keys(uniques).map(function(k) { return uniques[k]; });

console.log(mergedArr);
.as-console-wrapper { min-height: 100%; }

发布评论

评论列表(0)

  1. 暂无评论