在数组中查找并替换对象(基于ID)

时间:2019-02-25 23:23:47

标签: javascript arrays object ecmascript-6

在这里有点困惑...我想遍历allItems并返回allItems,但用与其ID相匹配的任何newItems代替。如何在id上寻找匹配项,然后将其替换为数组中的正确对象?

const allItems = [
  {
    'id': 1,
    'category_id': 1,
    'text': 'old',
  },
  {
    'id': 2,
    'category_id': 1,
    'text': 'old'
  }
]

const newItems = [
  {
    'id': 1,
    'category_id': 1,
    'text': 'new',
    'more_info': 'abcd'
  },
  {
    'id': 2,
    'category_id': 1,
    'text': 'new',
    'more_info': 'abcd'
  }
]

到目前为止我尝试过的事情:

for(let i = 0; i < allItems.length; i++) {
  if(newItems.indexOf(allItems[i].id) > -1){
    allItems[i] = newItems
  }
}

如何获取对象在newItems中的位置,然后将其替换为allItems

5 个答案:

答案 0 :(得分:5)

使用Array.mapArray.find()

t2$marker

在调用dataframe返回const allItems = [ { 'id': 1, 'category_id': 1, 'text': 'old' }, { 'id': 2, 'category_id': 1, 'text': 'old' } ]; const newItems = [ { 'id': 1, 'category_id': 1, 'text': 'new', 'more_info': 'abcd' }, { 'id': 2, 'category_id': 1, 'text': 'new', 'more_info': 'abcd' } ]; const result = allItems.map(x => { const item = newItems.find(({ id }) => id === x.id); return item ? item : x; }); console.log(result);时,甚至可以使用逻辑或返回原始项目来缩短此时间:

find

关于代码,您不能使用undefined,因为它仅在数组和对象的情况下比较原始值或引用。

答案 1 :(得分:1)

只需像这样使用map

const allItems = [{
    'id': 1,
    'category_id': 1,
    'text': 'old',
  },
  {
    'id': 2,
    'category_id': 1,
    'text': 'old'
  }
];
const newItems = [{
    'id': 1,
    'category_id': 1,
    'text': 'new',
    'more_info': 'abcd'
  },
  {
    'id': 2,
    'category_id': 1,
    'text': 'new',
    'more_info': 'abcd'
  }
];

const replacedItems = allItems.map(e => {
  if (newItems.some(({ id }) => id == e.id)) {
    return newItems.find(({ id }) => id == e.id);
  }
  return e;
});

console.log(replacedItems);

答案 2 :(得分:1)

只需使用一个简单的Array.map和一种方法来检查另一个数组。

const allItems = [
  {
    'id': 1,
    'category_id': 1,
    'text': 'old',
  },
  {
    'id': 2,
    'category_id': 1,
    'text': 'old'
  },
  {
    'id': 3,
    'category_id': 1,
    'text': 'old_same'
  }
  
]

const newItems = [
  {
    'id': 1,
    'category_id': 1,
    'text': 'new',
    'more_info': 'abcd'
  },
  {
    'id': 2,
    'category_id': 1,
    'text': 'new',
    'more_info': 'abcd'
  }
]

const findNewItem = (oldItem) => newItems.find(item => item.id === oldItem.id);

let arr = allItems.map(item => findNewItem(item)||item);

console.log(arr);

答案 3 :(得分:1)

根据输入数组的大小,您可以考虑添加一个中间步骤来构建newItems的“映射”,其中此映射的键是项的id

使用这样的映射可以使allItems数组中的项目与newItems数组中的项目进行更快的协调(和替换):

function replaceItemsOnId(items, replacement) {

  /* 
  Create a map where the key is the id of replacement items.
  This map will speed up the reconciling process in the 
  subsequent "map" stage
  */
  const replacementMap = replacement.reduce((map, item) => {

    map[ item.id ] = item
    return map;

  }, {})

  /*
  Map the items to a new array where items in the result array
  are either clones of the orignals, or replaced by items of 
  "replacement" array where thier id matches the item being mapped 
  */
  return items.map(item => {

    const use = replacementMap[ item.id ] || item

    return { ...use }

  })
}

const allItems = [
  {
    'id': 1,
    'category_id': 1,
    'text': 'old',
  },
  {
    'id': 2,
    'category_id': 1,
    'text': 'old'
  }
]

const newItems = [
  {
    'id': 1,
    'category_id': 1,
    'text': 'new',
    'more_info': 'abcd'
  },
  {
    'id': 2,
    'category_id': 1,
    'text': 'new',
    'more_info': 'abcd'
  }
]


console.log(replaceItemsOnId(allItems, newItems))

答案 4 :(得分:0)

您可以通过 id 获得对您要查找的对象的引用,但这还不够,因为那样您就需要索引才能将其替换为allItem(allItem[index] = newItem ),因此建议您先像这样找到该索引:

for (let item of newItems) {
    let indexNewItem = allItems.map(function (e) { return e.id }).indexOf(item.id);
    allItems[indexNewItem] = item
}

这应该有效