Сведение массива объектов к карте значения ключа

У меня есть массив объектов. Мне нужно создать объект, чтобы я мог получить имя на основе идентификатора.

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

Я пробовал это, что почти работает:

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

Однако он выводит:

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" 
}

Мне нужно:

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

Почему моя функция также разбивает одно из значений на символы?

🤔 А знаете ли вы, что...
JavaScript поддерживает асинхронное программирование с использованием промисов и асинхронных функций.


1
67
4

Ответы:

Решено

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.info(result)

Это будет работать

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

Вы можете сопоставить свой массив с массивом записей (пары ключ/значение), которые затем можно запустить через Object.fromEntries() для создания конечного объекта.

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.info(result)

Более длинная версия будет примерно такой

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`
}), {})

Проблема с вашим текущим кодом заключается в том, что результат...

accumulator[currentValue._id] = currentValue.name

это присвоенное значение (т.е. currentValue.name). При использовании в качестве аргумента в Object.assign() он разбивается на записи объекта, что приводит к тому, что вы видите с помощью

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

Просто передайте объект { [currentValue._id]: currentValue.name } в assign вместо присваивания 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.info(drinks.reduce(
  (accumulator, currentValue) => 
     Object.assign(accumulator, { [currentValue._id]: currentValue.name }), {}));