ImmutableJS:合并两个对象列表,而不复制它们

时间:2016-10-07 01:52:08

标签: javascript arrays javascript-objects immutable.js

假设我有以下内容:

var allFoods = Immutable.List();

var frenchFood = Immutable.List([
  {
  'type': 'french fries',
  'price': 3
  },
  {
    'type': 'petit gateau',
    'price': 40
  },
  {
    'type': 'croissant',
    'price': 20
  },
]);

var fastFood = Immutable.List([
  {
  'type': 'cheeseburger',
  'price': 5
  },
  {
  'type': 'vegan burger',
  'price': 20
  },
  {
  'type': 'french fries',
  'price': 3
  }
]);

我想合并两个列表,我也删除了dupes(在这种情况下,炸薯条),所以预期的结果是:

{
'type': 'french fries', // keep the first french fries
'price': 3
},
{
  'type': 'petit gateau',
  'price': 40
},
{
  'type': 'croissant',
  'price': 20
},
  {
'type': 'cheeseburger',
'price': 5
},
{
'type': 'vegan burger',
'price': 20
}

我正在尝试(不删除欺骗):

allFoods = frenchFood.concat(fastFood);
allFoods = allFoods.filter(function(item, pos) {
    return allFoods.indexOf(item) === pos;
});

返回的数组合并但仍然重复。

我错过了什么?

4 个答案:

答案 0 :(得分:2)

-

答案 1 :(得分:1)

我会使用var result = frenchFood.concat(fastFood).reduce( (reduction, food) => { if(reduction[food.type]) { return reduction; } else { return reduction.set([food.type], food); } }, new Immutable.Map()).valueSeq().toList();

{{1}}

答案 2 :(得分:0)

我强烈建议你不要在不可变结构中嵌入js对象。最好将这些对象包装在Immutable.Map()或者Immutable.fromJS(yourJsObj)中。

最少的代码

const results = Immutable.Set(frenchFood).union(Immutable.Set(fastFood));

然而@rooftop回答最快

https://jsperf.com/union-vs-concat-immutable

答案 3 :(得分:0)

我在媒介上找到了一个最佳解决方案(对我来说),链接到原始答案已失效:https://medium.com/@justintulk/merging-and-deduplicating-data-arrays-with-array-reduce-efaa4d7ef7b0

const arr1 = [
  { id: 1, name: 'Array 1-1' },
  { id: 2, name: 'Array 1-2' },
  { id: 3, name: 'Array 1-3' }
]
const arr2 = [
  { id: 1, name: 'Array 2-1' },
  { id: 3, name: 'Array 2-3' },
  { id: 4, name: 'Array 2-4' }
]

const mergeArrObjectsUnique = (currentArr, newArr) => {
  let obj = {}

  currentArr.forEach(item => {
    obj[item.id] = item
  })
  
  newArr.forEach(item => {
    obj[item.id] = item
  })
  
  let result = [];
  
  for(let p in obj) {
    if(obj.hasOwnProperty(p))
    result.push(obj[p])
  }

  console.log('result: ', result)
  return result
}

mergeArrObjectsUnique(arr1, arr2)