两个集合形成一个集合,用更新的字段替换重复集合

时间:2016-11-16 16:48:26

标签: javascript arrays json lodash

我有两个独特的集合,看起来像这样:

收集一:

[
 {
  id: 123,
  Name: Ben,
  Type: Car 
 },
 {
  id: 124,
  Name: Morgan,
  Type: Van
 },
 {
  id: 125,
  Name: Josh,
  Type: Bus
 }
]

收集二:

[
 {
  id: 123,
  Name: Ben,
  Type: House
 },
 {
  id: 124,
  Name: Morgan,
  Type: Flat
 },
 {
  id: 126,
  Name: Jack,
  Type: Landrover
 }
]

我确保两个集合中没有重复项,使用lodash _.uinqBy。

但是我想将两者合并在一起创建一个集合,但用匹配的id替换那些类型为=== "Car" || === "Van"

的集合。

因此,我将从上述集合中得到的结果是:

结果:

[
 {
  id: 123,
  Name: Ben,
  Type: Car 
 },
 {
  id: 124,
  Name: Morgan,
  Type: Van
 },
 {
  id: 125,
  Name: Josh,
  Type: Bus
 },
 {
  id: 126,
  Name: Jack,
  Type: Landrover
 }
]

无论如何,我可以用lodash做到这一点?或者其他任何方式?

提前致谢:)

3 个答案:

答案 0 :(得分:2)

使用lodash:

function unite(arr1, arr2) {
  return _(arr1)
    .concat(arr2) // concat the arrays
    .groupBy('id') // create a group by the id
    .map(function(group) { // in each group
      return _.find(group, function(item) { // find if one contains the request Type, and if not return the 1st in the group
        return item.Type === 'Car' || item.Type === 'Van'; 
      }) || _.head(group);
    })
    .values() // exract the values
    .value();
}

function unite(arr1, arr2) {
  return _(arr1)
    .concat(arr2) // concat the arrays
    .groupBy('id') // create a group by the id
    .map(function(group) { // in each group
      return _.find(group, function(item) { // find if one contains the request Type, and if not return the 1st in the group
        return item.Type === 'Car' || item.Type === 'Van'; 
      }) || _.head(group);
    })
    .values() // exract the values
    .value();
}

var arr1 = [{
  id: '123',
  Name: 'Ben',
  Type: 'Car'
}, {
  id: '124',
  Name: 'Morgan',
  Type: 'Flat'
}, {
  id: '125',
  Name: 'Josh',
  Type: 'Bus'
}];

var arr2 = [{
  id: '123',
  Name: 'Ben',
  Type: 'House'
}, {
  id: '124',
  Name: 'Morgan',
  Type: 'Van'
}, {
  id: '126',
  Name: 'Jack',
  Type: 'Landrover'
}];

var result = unite(arr1, arr2);

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

使用ES6 Map并传播:

const uniqueUnion = (arr1, arr2) => [
  ...arr1.concat(arr2)
  .reduce((m, item) => {
    if(!m.has(item.id) || item.Type === 'Car' || item.Type === 'Van') {
      m.set(item.id, item);
    }

    return m;
  }, new Map()).values()
];

const unite = (arr1, arr2) => [
  ...arr1.concat(arr2)
  .reduce((m, item) => {
    if (!m.has(item.id) || item.Type === 'Car' || item.Type === 'Van') {
      m.set(item.id, item);
    }

    return m;
  }, new Map()).values()
];

const arr1 = [{
  id: '123',
  Name: 'Ben',
  Type: 'Car'
}, {
  id: '124',
  Name: 'Morgan',
  Type: 'Flat'
}, {
  id: '125',
  Name: 'Josh',
  Type: 'Bus'
}];

const arr2 = [{
  id: '123',
  Name: 'Ben',
  Type: 'House'
}, {
  id: '124',
  Name: 'Morgan',
  Type: 'Van'
}, {
  id: '126',
  Name: 'Jack',
  Type: 'Landrover'
}];

const result = unite(arr1, arr2);

console.log(result);

答案 1 :(得分:1)

这是一个简单的javascript提案,它不会改变给定的数组。

var coll1 = [{ id: 123, Name: 'Ben', Type: 'Car' }, { id: 124, Name: 'Morgan', Type: 'Van' }, { id: 125, Name: 'Josh', Type: 'Bus' }],
    coll2 = [{ id: 123, Name: 'Ben', Type: 'House' }, { id: 124, Name: 'Morgan', Type: 'Flat' }, { id: 126, Name: 'Jack', Type: 'Landrover' }],
    hash = Object.create(null),
    merged = coll1.map(function (o) {
        hash[o.id] = {};
        Object.keys(o).forEach(function (k) {
            hash[o.id][k] = o[k];
        });
        return hash[o.id];
    });

coll2.forEach(function (o) {
    if (hash[o.id]) {
        if (o.Type === 'Van' || o.Type === 'Car') {
            hash[o.id].Type = o.Type;
        }
    } else {
        hash[o.id] = {};
        Object.keys(o).forEach(function (k) {
            hash[o.id][k] = o[k];
        });
        merged.push(hash[o.id]);
    }
});

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

答案 2 :(得分:1)

您可以对已连接的列表进行排序,然后根据邻域比较处理过滤:

var list1 = [{ id: 123, Name: 'Ben', Type: 'Car' }, { id: 124, Name: 'Morgan', Type: 'Van' }, { id: 125, Name: 'Josh', Type: 'Bus' }],
    list2 = [{ id: 123, Name: 'Ben', Type: 'House' }, { id: 124, Name: 'Morgan', Type: 'Flat' }, { id: 126, Name: 'Jack', Type: 'Landrover' }];

var finalList = list2.concat(list1).sort((a,b) => a.id - b.id).filter((x, i, arr) => {
  if (i < arr.length - 1){
    if (x.id !== arr[i+1].id || x.Type === "Car" || x.Type  === "Van") return true;
  }
  else if (x.id !== arr[i-1].id || x.Type === "Car" || x.Type  === "Van") return true;
});
console.log(finalList);