1

I have an array of objects. I need to make an object so that I can fetch the name based on an id.

const drinks = [
  { _id: "5fe40ad4d2e6e6de85c46a6c", name: "Americano", __v: 0 },
  { _id: "5fe40ad4d2e6e6de85c46a6d", name: "Latte", __v: 0 },
  { _id: "5fe40ad4d2e6e6de85c46a6e", name: "Flat White", __v: 0 }
];

I tried this which almost works:

console.log(drinks.reduce(
  (accumulator, currentValue) => 
     Object.assign(accumulator, accumulator[currentValue._id] = currentValue.name), {}));

However it outputs:

Object { 
  0: "F", 1: "l", 2: "a", 3: "t", 4: " ", 5: "W", 6: "h", 7: "i", 8: "t", 9: "e",
  5fe40ad4d2e6e6de85c46a6c: "Americano", 
  5fe40ad4d2e6e6de85c46a6d: "Latte", 
  5fe40ad4d2e6e6de85c46a6e: "Flat White" 
}

I need:

Object { 
  5fe40ad4d2e6e6de85c46a6c: "Americano", 
  5fe40ad4d2e6e6de85c46a6d: "Latte", 
  5fe40ad4d2e6e6de85c46a6e: "Flat White"
}

Why is my function also breaking down one of the values into characters?

4 Answers 4

3

const drinks = [{ _id: "5fe40ad4d2e6e6de85c46a6c", name: "Americano", __v: 0 },
                { _id: "5fe40ad4d2e6e6de85c46a6d", name: "Latte", __v: 0 },
                { _id: "5fe40ad4d2e6e6de85c46a6e", name: "Flat White", __v: 0 }];
                
                const result=drinks.reduce((acc,curr)=>{
                acc[curr._id]=curr.name;
                return acc;
                },{})
                
console.log(result)

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

Comments

3

You can map your array into an array of entries (key / value pairs) which you can then run through Object.fromEntries() to create the final object

const drinks = [
  { _id: "5fe40ad4d2e6e6de85c46a6c", name: "Americano", __v: 0 },
  { _id: "5fe40ad4d2e6e6de85c46a6d", name: "Latte", __v: 0 },
  { _id: "5fe40ad4d2e6e6de85c46a6e", name: "Flat White", __v: 0 }
]
                
const result = Object.fromEntries(drinks.map(({ _id, name }) =>
  [ _id, name ]))
  
console.log(result)

The longer version would be something like this

const result = drinks.reduce((obj, { _id, name }) => ({
  ...obj, // spread syntax is like `Object.assign()`
  [ _id ]: name // use `_id` as a dynamic object key with value `name`
}), {})

The issue with your current code is that the result of...

accumulator[currentValue._id] = currentValue.name

is the value assigned (ie currentValue.name). When used as an argument in Object.assign(), it is broken down as object entries, thus resulting in what you're seeing with

{ 
  0: "F", 
  1: "l", 
  2: "a", 
  3: "t", 
  4: " ", 
  5: "W", 
  6: "h", 
  7: "i", 
  8: "t", 
  9: "e"
}

1 Comment

Thanks for explaining what's going on!
1

Just pass the object { [currentValue._id]: currentValue.name } to assign instead of assignment accumulator[currentValue._id] = currentValue.name

const drinks = [
  { _id: "5fe40ad4d2e6e6de85c46a6c", name: "Americano", __v: 0 },
  { _id: "5fe40ad4d2e6e6de85c46a6d", name: "Latte", __v: 0 },
  { _id: "5fe40ad4d2e6e6de85c46a6e", name: "Flat White", __v: 0 }
];

console.log(drinks.reduce(
  (accumulator, currentValue) => 
     Object.assign(accumulator, { [currentValue._id]: currentValue.name }), {}));

1 Comment

Thanks, this is closest to what I was trying to achieve
-2

This will work

drinks.map(({ _id, name }) => ({
  [_id]: name
}))

1 Comment

This will output an array of objects, not a single object...

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.