Reputation: 14773
Assuming I have the following array: const props = ["category", "category_name"]
and the following object:
const obj = {
category: {
category_name: "some name",
}
}
how can I built a property accessor based on the array, so that I can access: "some name"
?
I know there is a method in Lodash get in which you can pass in a path to get the object like 'category.category_name'
so a simple props.join(".")
would work here. But I want to not use Lodash.
Upvotes: 1
Views: 122
Reputation: 6818
This is a good candidate for Array.prototype.reduce()
.
props.reduce((acc, prop) => acc?.[prop], obj)
The .reduce()
method iterates over each element in the array that it is called on and passes both the current element and the value that the previous invocation resolved to, to the next iteration.
It is basically equivalent to
let acc = obj;
for (let prop of props) {
acc = acc[prop];
}
return acc;
I also added the optional chaining operator (?.
) so that when the element can't be found, it returns undefined
instead of throwing an error.
const obj = {
category: {
category_name: "some name",
}
};
const props = ["category", "category_name"];
const props2 = ["does_not_exist", "category_name"];
console.log(props.reduce((acc, prop) => acc?.[prop], obj));
console.log(props2.reduce((acc, prop) => acc?.[prop], obj));
// Without optional chaining operator
console.log(props.reduce((acc, prop) => acc[prop], obj));
console.log(props2.reduce((acc, prop) => acc[prop], obj));
Upvotes: 0
Reputation: 2471
Use forEach
like that.
const props = ["category", "category_name"]
const obj = {
category: {
category_name: "some name",
}
}
function propertyAccessor(obj, props){
let value = obj;
props.forEach(name => value = value[name])
return value;
}
console.log(propertyAccessor(obj, props))
Upvotes: 1