查找和替换数组中的对象(基于 id)
Posted
技术标签:
【中文标题】查找和替换数组中的对象(基于 id)【英文标题】:Find and replace object in array (based on id) 【发布时间】:2019-07-19 10:47:07 【问题描述】:这里有点谜...我想遍历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
?
【问题讨论】:
【参考方案1】:使用Array.map
和Array.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
,因为它只比较数组和对象的原始值或引用。
【讨论】:
【参考方案2】:只需像这样使用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);
【讨论】:
【参考方案3】:只需使用一个简单的 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);
【讨论】:
【参考方案4】:根据输入数组的大小,您可以考虑添加一个中间步骤来构建您的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))
【讨论】:
【参考方案5】:您可以通过 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
这应该可以工作
【讨论】:
以上是关于查找和替换数组中的对象(基于 id)的主要内容,如果未能解决你的问题,请参考以下文章