Question on Functional Programming - reduce Method

hello everyone,

I have a little question on one of the example how reduce method can be used as below:

const users = [
  { name: 'John', age: 34 },
  { name: 'Amy', age: 20 },
  { name: 'camperCat', age: 10 }
];

const usersObj = users.reduce((obj, user) => {
  obj[user.name] = user.age;
  return obj;
}, {});
console.log(usersObj);

my question lies on this line of code

obj[user.name] = user.age;

why is that to show the property name we need put user.name inside obj[ ] meanwhile user.age can be just written like so?

Have you looked at the output?

[
  { name: 'John', age: 34 },
  { name: 'Amy', age: 20 },
  { name: 'camperCat', age: 10 }
]

Gets turned into

{
  John: 34,
  Amy: 20,
  camperCat: 10
}

You can use variables in bracket notation to access properties of an object.

const key = "name";
const value = "Colin";
const obj = {};
obj[key] = value;

console.log(obj.name) // Colin

Let’s say you have the following object:

const foo = {
  word: "string",
  5: "number",
  user: {
    name: "Frank"
  },
  Bob: "A palindrome"
};

If the key you need is a noun without spaces, you can use either method to call it. If there is a space, you can only use [] to access it. The advantage of using [] is that you can also use variables and expressions to generate the key name:

console.log("These are the same:")
console.log(foo.word);         // "string"
console.log(foo["word"]);      // "string"
console.log(foo["wo" + "rd"]); // "string"
const w = "word";
console.log(foo[w]);           // "string"

If the key is a number, then you can only use [] to access it:

console.log("And these are the same:")
console.log(foo[5]);          // "number"
console.log(foo[2 + 3]);      // "number"
const n = 13 - 8;
console.log(foo[n])           // "number"

If you call foo.user.name, it will look for an object called ‘user’ inside ‘foo’, then look for a variable called ‘name’ inside that object, and return the associated value. If you call foo[user.name], it will first find the value of ‘user.name’ for some object called ‘user’, then look for a variable inside ‘foo’ with that name:

console.log("But these are different:")
const user = {
  name: "Bob"
};

console.log(foo.user.name);  // "Frank"
console.log(foo[user.name]); // foo["Bob"]=="A palindrome"

You can play with the example code here:

1 Like

Thanks a lot for explaining it clearly!
I need sometime to digest it, but so far based on my understanding with your example above is that foo.user.name isn’t equal to foo[user.name] yeah?

Hi there,

my confusion is that why value doesn’t need to be put in bracket notation but the properties name need to be accessed with bracket notation.

That’s right. When you use foo.user.name, it first looks for something inside foo called user, then it looks for something inside foo.user that is called name. In my example, foo.user.name is “Frank”. When you use foo[user.name], it looks for an object outside of foo called user, then it returns the variable called name inside it. In my example, user.name is “Bob”. Once it has “Bob”, it looks for foo["Bob"], which is the same as foo.Bob. In other words, it returns the variable called Bob inside foo. In my example, that is “A palindrome”.

Consider another example in which the object we are trying to read does not contain any objects named user:

const friends = {
  Sam: "My best friend.",
  Max: "Mostly okay."
};

const user = {
  name: "Sam",
  age: 27
};

console.log(friends["Sam"]);
console.log(friends.Sam);
console.log(friends[user.name]);
console.log(friends.user.name);

The first three lines in the console will be the same: “My best friend.” The last line will be an error, because friends.user does not exist, so it is impossible to read the variable name from it.

2 Likes

It is a computed property name (key). The expression in brackets [] will be computed and used as the property name.


let index = 0;
const names = ['Rick', 'Bob', 'Sterling'];
const users = {};

users[names[index]] = 'Sanchez'
users[names[++index]] = 'Belcher'
users[names[++index]] = 'Archer'

console.log(users); // { Rick: 'Sanchez', Bob: 'Belcher', Sterling: 'Archer' }

If we write it like this it might be more clear.

const users = [
  { name: 'John', age: 34 },
  { name: 'Amy', age: 20 },
  { name: 'camperCat', age: 10 },
];

const usersObj = users.reduce((obj, user) => {
  const key = user.name;
  const value = user.age;

  obj[key] = value;
  return obj;
}, {});

console.log(usersObj); // { John: 34, Amy: 20, camperCat: 10 }

got it! thank you!! :smiley:

yep i got it now, thanksss