Unique array of objects and merge duplications using lodash or underscore

吃可爱长大的小学妹 提交于 2019-12-25 09:31:27

问题


I have an array of objects that can contain duplicates, but I'd like uniquify the array by a property, and then I want to merge properties of the duplicates conditionally. For example, give the array below

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
   }
]

Knowing each object has name, propertyA, propertyB, and propertyC, I'd like to uniquify by the name property, and keep the true values for propertyA, propertyB, and propertyC. So the above array becomes,

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

What is the best way to go about this using lodash/underscore?


回答1:


You could do it using _.uniqWith, but it would require you to mutate one of the parameters before returning the boolean value of whether they are equal, so I don't recommend it.

A better option is to use _.groupBy followed by _.map in order to group the unique names, and then customize how you combine them. In your case, you can combine the same-named objects using _.assignWith and then give a logical or || operation as the combining function.

With ES6, it becomes nearly a one-liner:

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>



回答2:


With plain Javascript, you could use a hash table as reference to unique objects with the same name and collect the values in a loop over the keys and update with logical OR.

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);
.as-console-wrapper { max-height: 100% !important; top: 0; }


来源:https://stackoverflow.com/questions/43877957/unique-array-of-objects-and-merge-duplications-using-lodash-or-underscore

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!