supersize
supersize

Reputation: 14773

Build object accessor from array in vanilla JS

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

Answers (2)

Ivar
Ivar

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

Lukas249
Lukas249

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

Related Questions