I want to optimize the extraction of a property's value from an array of objects, each object containing other nested arrays of objects, in Javascript.
I'm not really sure how to explain it by words, so here is some code to explain what I'm trying to optimize:
// test case
var first = [
{ second: [ { id: 1}, { id: 2}, { id: 3} ] },
{ second: [ { id: 4}, { id: 5}, { id: 6} ] },
{ second: [ { id: 7}, { id: 8}, { id: 9} ] },
{ second: [ { id: 10}, { id: 11}, { id: 12} ] }
];
// where the id values will be stored
var arrIDs = [];
// extracting the id values
for (var i=0; i<first.length; i++){
for (var j=0; j<first[j].second.length; j++){
// I want to avoid all these push() calls
arrIDs.push(first[j].second[j].id);
}
}
arrIDs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
You could use this recursive ES6 function. It works for any level, and you can pass it an array, plain object, or anything else (in the latter case you get an empty array as result):
function getAll(obj, key) {
return obj !== Object(obj) ? []
: Object.keys(obj).reduce ( (acc, k) =>
acc.concat(k == key ? obj[k] : getAll(obj[k], key)), [] );
}
// sample data with different levels and mix of array / object alterations
var first = [
{ a: 2, id: 1}, { second: [ { id: 2}, { id: 3} ] },
{ second: [ { id: 4}, { id: 5}, { id: 6} ] },
{ second: [ { id: 7}, { third: {id: 6}}, { id: 9} ] },
{ second: [ { id: 10}, { id: 11}, { id: 12} ] }
];
var result = getAll(first, 'id');
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
For IE8 compatibility:
function getAll(obj, key) {
if (typeof obj != 'object' || obj == null) return [];
var acc = [];
for (var k in obj) {
acc = acc.concat( k == key ? obj[k] : getAll(obj[k], key) );
}
return acc;
}
// sample data with different levels and mix of array / object alterations
var first = [
{ a: 2, id: 1}, { second: [ { id: 2}, { id: 3} ] },
{ second: [ { id: 4}, { id: 5}, { id: 6} ] },
{ second: [ { id: 7}, { third: {id: 6}}, { id: 9} ] },
{ second: [ { id: 10}, { id: 11}, { id: 12} ] }
];
var result = getAll(first, 'id');
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }