For example if we have an existing object
const mainObject = {
title: 'some title',
topics: {
topic1: {
path: '',
id: 1
},
topic2: {
path: '',
id: 2
}
}
}
and I have a function that gets array containing keys for example
const arrayOfKeys = ['topics', 'topic1'];
function getObjectByKeys(arrayOfKeys) {
// problem is length of the array may change
const myObject = mainObject[arrayOfKeys[0]][arrayOfKeys[1]];
return myObject;
}
function should return
{
path: '',
id: 1
}
You can use .reduce
here. Initialise the accumulator with the main object and on each iteration of its callback return the value corresponding to current key.
const mainObject = { title: 'some title', topics: { topic1: { path: '', id: 1 }, topic2: { path: '', id: 2 } } } const arrayOfKeys = ['topics', 'topic1']; function getObjectByKeys(arrayOfKeys) { return arrayOfKeys.reduce((a, el, i, arr) => { return a[el] || {}; }, mainObject); } console.log(getObjectByKeys(arrayOfKeys));
One possible solution could be using the forEach
loop.
const mainObject = { title: 'some title', topics: { topic1: { path: '', id: 1 }, topic2: { path: '', id: 2 } } } const arrayOfKeys = ['topics', 'topic1']; function getObjectByKeys(arrayOfKeys) { let result = Object.assign({}, mainObject); arrayOfKeys.forEach(function(key){ result = result[key]; }); return result; } console.log(getObjectByKeys(arrayOfKeys));
Another approach is to use reduce
method by passing a callback
function as argument.
const mainObject = { title: 'some title', topics: { topic1: { path: '', id: 1 }, topic2: { path: '', id: 2 } } } const arrayOfKeys = ['topics', 'topic1']; getObjectByKeys = (arrayOfKeys) => { return arrayOfKeys.reduce((obj, item) => obj[item], mainObject); } console.log(getObjectByKeys(arrayOfKeys));
You can use reduce()
const mainObject = { title: 'some title', topics: { topic1: { path: '', id: 1 }, topic2: { path: '', id: 2 } } }; const arrayOfKeys = ['topics', 'topic1']; var aa= arrayOfKeys.reduce((carry,value,index)=>{ return carry[value]; },mainObject); console.log(aa);
you can use recursive.
const mainObject = { title: 'some title', topics: { topic1: { path: '', id: 1 }, topic2: { path: '', id: 2 }, topic3: { path: 'more depth', subtopic: { path: '', id: 4 }, id: 3 } } } const arrayOfKeys = ['topics', 'topic3', 'subtopic']; function getObjectByKeys(arrayOfKeys, currentObj, index = 0) { if(index >= arrayOfKeys.length) { return currentObj; } return getObjectByKeys(arrayOfKeys, currentObj[arrayOfKeys[index]], index+1) } console.log(getObjectByKeys(arrayOfKeys, mainObject));
you can edit your function as below and it will give you desired output.
function getObjectByKeys(obj, [first, ...rest]) {
if(rest.length > 0 ) return getObjectByKeys(obj[first], rest)
else return obj[first]
}
getObjectByKeys(mainObject, ['topics', 'topic1'])
I would change topics into an array so finding any element becomes trivial. The code is almost human readable now: "find entry with id 1 inside field_name of mainObject."
const mainObject = { title: 'some title', topics: [ { id: 1, path: 'first' }, { id: 2, path: 'second' } ] }; const field_name = 'topics'; const entry_to_find = 1; const entry = mainObject[ field_name ].find( entry => entry.id === entry_to_find ); console.log( entry );
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.