使用lodash或下划线的唯一对象数组和合并重复

时间:2017-05-09 19:04:26

标签: javascript arrays underscore.js lodash

我有一个可以包含重复项的对象数组,但我想通过属性对数组进行统一,然后我想有条件地合并重复项的属性。例如,给出下面的数组

var array = [
   {
     name: 'object1',
     propertyA: true,
     propertyB: false,
     propertyC: false 
   },
   {
     name: 'object2',
     propertyA: false,
     propertyB: true,
     propertyC: false
   },
   {
     name: 'object1',
     propertyA: false,
     propertyB: true,
     propertyC: false
   }
]

知道每个对象都有name,propertyA,propertyB和propertyC,我想通过name属性进行unquify,并保留propertyA,propertyB和propertyC的真值。所以上面的数组就变成了,

var updatedArray = [
   {
     name: 'object1',
     propertyA: true,
     propertyB: true,
     propertyC: false 
   },
   {
     name: 'object2',
     propertyA: false,
     propertyB: true,
     propertyC: false
   }
]

使用lodash / underscore进行此操作的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

你可以使用_.uniqWith来做,但它需要你在返回它们是否相等的布尔值之前改变其中一个参数,所以我不推荐它。

更好的选择是使用_.groupBy后跟_.map以对唯一名称进行分组,然后自定义组合方式。在您的情况下,您可以使用_.assignWith组合相同名称的对象,然后将逻辑或||操作作为组合函数。

使用ES6,它几乎成为一个单行:

var array = [{"name":"object1","propertyA":true,"propertyB":false,"propertyC":false},{"name":"object2","propertyA":false,"propertyB":true,"propertyC":false},{"name":"object1","propertyA":false,"propertyB":true,"propertyC":false}];
    
var updatedArray =
  _(array)
    .groupBy('name')
    .map(objs => _.assignWith({}, ...objs, (val1, val2) => val1 || val2))
    .value();
    
console.log(updatedArray);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

答案 1 :(得分:0)

使用普通的Javascript,您可以使用哈希表作为对具有相同名称的唯一对象的引用,并在键上循环收集值并使用逻辑OR进行更新。

&#13;
&#13;
var array = [{ name: 'object1', propertyA: true, propertyB: false, propertyC: false }, { name: 'object2', propertyA: false, propertyB: true, propertyC: false }, { name: 'object1', propertyA: false, propertyB: true, propertyC: false }],
    unique = array.reduce(function (hash) {
        return function (r, a) {
            if (!hash[a.name]) {
                hash[a.name] = { name: a.name };
                r.push(hash[a.name]);
            }
            Object.keys(a).forEach(function (k) {
                if (k !== 'name') {
                    hash[a.name][k] = hash[a.name][k] || a[k];
                }
            });
            return r;
        };
    }(Object.create(null)), []);

console.log(unique);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
&#13;
&#13;