I have an array of objects, example:
[
{
"fName": "Jon",
"lName": "Doe",
"age": "30",
"shirtSize": "M"
},
{
"fName": "Jane",
"lName": "Foe",
"age": "25",
"shirtSize": "M"
},
...
]
I also have a list of keys, example:
["age", "shirtSize"]
I want to take the array of objects, and build a new array of objects that match the key list array, effectively filtering the array of objects to only have the key/value pairs I want. The above are examples, and the real datasets are of course more verbose. I've brute forced it in my algorithm below and as expected, it's not very performant at all, as a result of my loop within the map. My result is like:
[
{
"age": "30",
"shirtSize": "M"
},
{
"age": "25",
"shirtSize": "M"
},
...
]
I am not using anything like lodash. How can I improve this performance?
const data = [
{
"fName": "Jon",
"lName": "Doe",
"age": "30",
"shirtSize": "M"
},
{
"fName": "Jane",
"lName": "Foe",
"age": "25",
"shirtSize": "M"
}
];
const keyList = ["age", "shirtSize"];
const filteredDataset = data.map((elem) => {
let tempHolder = {};
for (let key of keyList) {
tempHolder[key] = elem[key];
}
return tempHolder;
});
return filteredDataset;
CodePudding user response:
var results = [];
for(var person of data){
var obj = {};
for(var key of keyList){
obj[key] = person[key];
}
results.push(obj);
}
The first loop iterates through data, and the inner loop iterates through keyList and adds those attributes to the temporary object, which is then pushed to the results array.
EDIT: Your code is basically the same, with yours just using map to iterate through instead of a for...of loop.
CodePudding user response:
You can express the same algorithm more declaratively:
const select = (props) => (objs) =>
objs .map (o => Object .fromEntries (props .map (p => [p, o[p]])))
const items = [{fName: "Jon", lName: "Doe", age: "30", shirtSize: "M"}, {fName: "Jane", lName: "Foe", age: "25", shirtSize: "M"}]
console .log (select (["age", "shirtSize"]) (items))
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>