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

11

我这里有一个小难题……我想循环遍历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 中?

6个回答

15
使用 Array.mapArray.find()

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时返回原始项:

const result = allItems.map(x => newItems.find(({ id }) => id === x.id) || x);

关于你的代码,你不能使用 indexOf,因为它只比较原始值或者数组和对象的引用。


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);


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);


1
根据输入数组的大小,您可能需要添加一个中间步骤来构建“映射”,其中此映射的键是项目的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))


0
这个问题的答案大多数都是通过循环遍历原始数组来查看应该替换哪些项。如果原始数组很大,并且您不需要替换太多,改变逻辑可能会更好地提高性能。我只需要在一个数组(客户)中替换一个项目。我是这样做的:
    const index = customers.findIndex(x => x.Id == editedCust.Id);
    if (index >= 0)
      customers[index] = editedCust;

你可以迭代遍历 newItems 中的所有项目,针对每个项目执行上述操作。

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
}

这应该可以工作


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接