I have a list of ids as reference, and I have an object which contains multiple objects that have array of objects.
I want to make an array of objects with corresponding ids in the list, the FASTEST way.
const data = { "items": { "item1": [{ "id": "id1", "info": "info1" }, { "id": "id2", "info": "info22" } ], "item20": [{ "id": "id3", "info": "info5" }], "item5": [{ "id": "id4", "info": "info6" }, { "id": "id5", "info": "info7" } ] } }; const keep = ['id4', 'id2']; const results = []; keep.forEach(function(val) { const match = Object.keys(data.items).map(item => { return data.items[item].find(obj => obj.id === val) }); results.push(match) }) console.log('final: ', results)
the current is not returning what i want. the expected result will be:
[
{
"id": "id2",
"info": "info22"
},
{
"id": "id4",
"info": "info6"
}
]
How about in the case if the data is itself an array of objects, and we want to do the same for each one?
const data = [{ "otherStuff": "otherB", "items": { "item1": [{ "id": "id1", "info": "info1" }, { "id": "id2", "info": "info22" } ], "item20": [{ "id": "id3", "info": "info5" }], "item5": [{ "id": "id4", "info": "info6" }, { "id": "id5", "info": "info7" } ] } }, { "otherStuff": "otherA", "items": { "item1": [{ "id": "id1", "info": "info10000" }, { "id": "id2", "info": "info220000" } ], "item20": [{ "id": "id3", "info": "info5000" }], "item5": [{ "id": "id4", "info": "info60000" }, { "id": "id5", "info": "info7000" } ] } }]; const keep = ['id4', 'id2']; const results = []; keep.forEach(function(val) { data.forEach(function(entry){ Object.keys(entry.items).forEach(item => { var match = entry.items[item].find(obj => obj.id === val); if (match) { results.push(match) } }); }); }) console.log(results)
and the output should be:
[
{
"otherStuff": "otherB",
"items": [
{
"id": "id2",
"info": "info22"
},
{
"id": "id4",
"info": "info6"
}
]
},
{
"otherStuff": "otherA",
"items": [
{
"id": "id2",
"info": "info220000"
},
{
"id": "id4",
"info": "info60000"
}
]
}
]
the result is not the same though.
If you use a Set for the kept ids, you save one O(n) traversal:
const keep = new Set(['id4', 'id2']);
const result = [];
for(const items of Object.values(data.items))
for(const item of items)
if(keep.has(item.id))
result.push(item);
You do not need to use map()
. Simply use forEach()
loop on the object keys which you want to keep and find the matching object so that it can be pushed into the result array.
const data = { "items": { "item1": [{ "id": "id1", "info": "info1" }, { "id": "id2", "info": "info22" } ], "item20": [{ "id": "id3", "info": "info5" }], "item5": [{ "id": "id4", "info": "info6" }, { "id": "id5", "info": "info7" } ] } }; const keep = ['id4', 'id2']; const results = []; keep.forEach(function(val) { Object.keys(data.items).forEach(item => { var match = data.items[item].find(obj => obj.id === val); if (match) { results.push(match) } }); }) console.log('final: ', results)
items is an object & item1
, item20
are are keys.So you can do Object.values
and apply reduce function on it to get a single array which is consist of all the objects. No iterate the keep
array and filter out the required element from the single array.
const data = { "items": { "item1": [{ "id": "id1", "info": "info1" }, { "id": "id2", "info": "info22" } ], "item20": [{ "id": "id3", "info": "info5" }], "item5": [{ "id": "id4", "info": "info6" }, { "id": "id5", "info": "info7" } ] } }; const keep = ['id4', 'id2']; let getAllObjectValues = Object.values(data.items).reduce(function(acc, curr) { curr.forEach((elem) => { acc.push(elem) }) return acc; }, []); let k = keep.map(function(item) { return getAllObjectValues.filter(function(val) { return item === val.id })[0] }) console.log(k)
You've used an assignment operator rather than an equivalence operator in your map function, change to:
const keep = ['id4', 'id2'];
const results = [];
keep.forEach(function(val){
const match = Object.keys(data.items).map(item => {
return data.items[item].find(obj => obj.id === val)
});
results.push(match)
})
console.log('final: ', results)
Using a combination of reduce
and filter
you can iterate each sub-array checking whether the value should be kept.
const data = { "items": { "item1": [ { "id": "id1", "info": "info1" }, { "id": "id2", "info": "info22" } ], "item20": [ { "id": "id3", "info": "info5" } ], "item5": [ { "id": "id4", "info": "info6" }, { "id": "id5", "info": "info7" } ] } }; const keep = ['id4', 'id2']; const filter = el => { return keep.indexOf(el.id) >= 0; }; const reducer = (accumulator, currentValue) => { return accumulator = accumulator.concat(data.items[currentValue].filter(filter)); }; let results = Object.keys(data.items).reduce(reducer, []); console.log('final: ', results);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.