使用lodash在单个数组中合并重复对象

时间:2016-11-08 11:28:54

标签: javascript arrays json underscore.js lodash

我试图在我收到的json数组中合并重复的对象。

数组如下所示:

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

出于某种原因,我无法弄清楚如何合并重复项。

我尝试过首先将所有名称映射为小写,然后使用unique,但这会删除其他props的值。

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

是否有人知道如何使用lodash解决我的问题?

4 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

Pure JS ES6你可以这样做;

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);

答案 2 :(得分:0)

我不确定lodash或下划线,但供参考:一个vanilla js解决方案。可能很高兴使用一个起点并将其中的部分转换为它们的库等价物。

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%; }

答案 3 :(得分:0)

您可以使用lodash _.groupBy() _.map()_.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.com/ajax/libs/lodash.js/4.16.6/lodash.min.js"></script>
&#13;
&#13;
&#13;