1

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.

2 Answers 2

1

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))

Sign up to request clarification or add additional context in comments.

3 Comments

thanks, yeah that would work but I gotta admit I was hoping for more of a one liner.
@Ivar I guess so ;) wanna do an answer?
@supersize why do you care about the line count?
0

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));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.