[英]Replace value in one array with matching properties from second array
I've got two arrays:我有两个数组:
arrayOne = ["green","blue","purple"]
and和
arrayTwo = [
{ name: "green", id: 1 },
{ name: "red", id: 2 },
{ name: "yellow", id: 3 },
{ name: "blue", id: 8 },
]
I want the return array to be [1, 8, 9]
, with "purple" being pushed as an object at the end of arrayTwo
(with a new id).我希望返回数组为
[1, 8, 9]
,在arrayTwo
末尾将“purple”作为对象arrayTwo
(带有新的 id)。
What's the most efficient way to go about this?解决此问题的最有效方法是什么?
The following code uses map
to either retrieve the id
of the element in the second array or, if that element doesn't exist, create a new one by incrementing the last id
in that array by 1.以下代码使用
map
来检索第二个数组中元素的id
,或者,如果该元素不存在,则通过将该数组中的最后一个id
增加 1 来创建一个新元素。
arrayOne = ["green","blue","purple"] arrayTwo = [ { name: "green", id: 1 }, { name: "red", id: 2 }, { name: "yellow", id: 3 }, { name: "blue", id: 8 }, ] const newArr = arrayOne.map(color => { const found = arrayTwo.find(el => el.name === color); if (found) { return found.id; } const newId = arrayTwo[arrayTwo.length - 1].id + 1; arrayTwo.push({ name: color, id: newId }); return newId; }); console.log(newArr); console.log(arrayTwo);
Edit: Note that it may be brittle to assume the last item in arrayTwo contains the highest id.编辑:请注意,假设 arrayTwo 中的最后一项包含最高 id 可能很脆弱。 In that case, you can always find the max ID:
在这种情况下,您始终可以找到最大 ID:
const newArr = arrayOne.map(color => {
let maxId = 0;
const found = arrayTwo.find(el => {
if (el.id > maxId) {
maxId = el.id;
}
return el.name === color
});
if (found) {
return found.id;
}
const newId = maxId + 1;
arrayTwo.push({ name: color, id: newId });
return newId;
});
A thought on efficiency关于效率的思考
If you have any concerns about efficiency if this is going to be a large (hundreds/thousands/more) element arrays, you can consider changing arrayTwo
to an object with color as a key:如果您对效率有任何顾虑,如果这将是一个大型(数百/数千/更多)元素数组,您可以考虑将
arrayTwo
更改为以颜色为键的对象:
const arrayOne = ["green","blue","purple"]; const arrayTwo = [ { name: "green", id: 1 }, { name: "red", id: 2 }, { name: "yellow", id: 3 }, { name: "blue", id: 8 }, ]; let maxId = 0; // Create map const arrayTwoMap = arrayTwo.reduce((acc, el) => { if (el.id > maxId) maxId = el.id; acc[el.name] = el.id; return acc; }, {}); // Find elements const newArr = arrayOne.map(el => { const found = arrayTwoMap[el]; if (found !== undefined) { return found; } const newId = maxId + 1; arrayTwoMap[el] = newId; return newId; }); console.log(newArr);
You can convert arrayTwo
into a Map
(for efficiency), where the name
is the key and the id
is the value.您可以将
arrayTwo
转换为Map
(为了效率),其中name
是键, id
是值。 Then, once you have done that, you can .map()
arrayOne
into an array of id
by using each name element as a look-up key to get its associated id.然后,一旦你这样做了,你就可以
.map()
arrayOne
到一个id
数组中,方法是使用每个 name 元素作为查找键来获取其关联的 id。 If you find a name
which is not in the Map
, then you can add a new object, to your arrayTwo
array, and increment the id
counter:如果您找到一个不在
Map
的name
,那么您可以将一个新对象添加到您的arrayTwo
数组中,并增加id
计数器:
const arrayOne = ["green","blue","purple"]; const arrayTwo = [{ name: "green", id: 1 }, { name: "red", id: 2 }, { name: "yellow", id: 3 }, { name: "blue", id: 8 },]; let [{id:l_id}] = arrayTwo.slice(-1); const lut = new Map(arrayTwo.map(({name, id}) => [name, id])); const res = arrayOne.map(name => lut.get(name) || (arrayTwo.push({name, id: ++l_id}), l_id)); console.log(res); console.log(arrayTwo);
If you're only concerned about the return value (and not changing array 2), you can simplify the code down:如果您只关心返回值(而不是更改数组 2),您可以简化代码:
const arrayOne = ["green","blue","purple"]; const arrayTwo = [{ name: "green", id: 1 }, { name: "red", id: 2 }, { name: "yellow", id: 3 }, { name: "blue", id: 8 },]; let [{id:l_id}] = arrayTwo.slice(-1); const lut = new Map(arrayTwo.map(({name, id}) => [name, id])); const res = arrayOne.map( name => lut.get(name) || ++l_id ); console.log(res);
this code can achieve what you want:这段代码可以实现你想要的:
let arrayTwo = [ { name: "green", id: 1 }, { name: "red", id: 2 }, { name: "yellow", id: 3 }, { name: "blue", id: 8 }, ]; let indexes = {}, lastId = 0; arrayTwo.forEach(({name, id}) => { if(indexes[name] = id, id > lastId) lastId = id }); function getResult(a){ return a.map(e => indexes[e] || (arrayTwo.push({name: e, id: ++lastId}), indexes[e] = lastId)) } // arrayOne contents let result = getResult(["green", "blue", "purple"]); console.log(arrayTwo, result); // with other data let result2 = getResult(["cyan", "blue", "purple", "azure"]); console.log(arrayTwo, result2);
Hope it helps希望能帮助到你
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.