Изменить массив в JavaScript в более простой объект

17

У меня есть простой JSON с массивом, который содержит дополнительные объекты и т. Д., Как это:

languagePack:
[
  {
    'key': 'Username',
    'value': 'Benutzername',
    'group': 'default'
  },
  {
    'key': 'Password',
    'value': 'Passwort',
    'group': 'default'
  }
]

Но то, что я действительно хочу, это такой объект:

languagePack: 
{
    'Username': 'Benutzername',
    'Password': 'Passwort'
}

Итак, я хочу сократить массив до простых пар ключ-значение, которые находятся внутри массива или даже объекта (ключи уникальны). У кого-нибудь есть идеи, как уменьшить это с некоторыми из этих классных функций массива? Я только придумал что-то вроде «для каждого» и построил свойство объекта «вручную» для свойства, но я помню, что были некоторые классные вещи для массива, такие как «уменьшить», оператор распространения (...), карта, каждый, некоторые и т. д.

Я попробовал это с чем-то вроде:

var temp = this.languagePack.map(([key, value]) => ({key,value}))
console.log(temp)

Но это только заставило меня получить сообщение об ошибке TypeError: Invalid attempt to destructure non-iterable instance

Изменить: все три ответа работают отлично. Спасибо.

Марсель Грюгер
источник
groupДолжны быть проигнорированы?
Берги
Да, группу можно игнорировать, моя коллега представлял собой идею использовать один и тот же ключ на разных экранах с разными переводами, но я не могу найти для него никакого реального применения. Но это еще один вопрос для намного позже :)
Марсель Грюгер

Ответы:

11

В основном вам нужно использовать forEachвместо mapфункции, а затем вы можете построить этот объект для любой пары ключ-значение, которое вы хотите сохранить.

Попробуйте это, это решит вашу проблему.

var temp = {};

this.languagePack.forEach(({key,value}) => {
    temp[key] = value
})

console.log(temp)

Примечание: здесь мы не используем, mapпотому что мы хотим вернуть объект, а не массив, поэтому мы можем использовать reduceфункцию здесь, чтобы сделать это, но я подумал, что было бы просто и легко понять, что мы хотим и что мы здесь делаем.

ma_dev_15
источник
10

Вы можете использовать reduceфункцию javascript, чтобы создать пустой объект и поместить в него каждый ключ и значение.

const data = [
  {
    'key': 'Username',
    'value': 'Benutzername',
    'group': 'default'
  },
  {
    'key': 'Password',
    'value': 'Passwort',
    'group': 'default'
  }
];

const newData = data.reduce((acc, row) => {
  acc[row.key] = row.value;
  return acc;
}, {});

console.log(newData);

Изменить: Хорошее предложение Донни Verduijn . Вы можете использовать es6 destructuring, чтобы написать функцию короче.

const newData = data.reduce((acc, { key, value }) => ({ ...acc, [key]: value }), {});
Максим Жиру
источник
3
Если вы хотите использовать синтаксис ES6, вы также можете реализовать функцию сокращения таким образом(acc, { key, value }) => ({ ...acc, [key]: value })
Донни Вердуйн
1
Также вы можете использовать оператор запятой, чтобы избежать возврата:const newData = data.reduce((acc, row) => (acc[row.key] = row.value, acc), {});
ElChiniNet
4
Просто из любопытства. Некоторое время назад я тестировал производительность оператора распространения для деструктурирования объектов, и даже если это правда, что иногда это улучшает читабельность кода, он имеет высокую стоимость: measurethat.net/Benchmarks/Show/6194/5/ …
ElChiniNet
@ElChiniNet Тестовый пример, который вы связали, касается распространения массива, а не распространения объекта. (Но да, многократное распространение в новый объект намного медленнее, чем мутирование одного объекта)
Берги
1
@Bergi, здесь у вас есть сравнение этого конкретного кода: measurethat.net/Benchmarks/Show/6318/0/…
ElChiniNet
6

использовать вместе с Array#mapего созданием ключ и значение в качестве объекта и Object.assignскрытое значение массива для объекта

const languagePack = [ { 'key': 'Username', 'value': 'Benutzername', 'group': 'default' }, { 'key': 'Password', 'value': 'Passwort', 'group': 'default' } ];

var res = Object.assign({},...languagePack.map(({key,value}) => ({[key]:value})))

console.log(res)

Prasanth
источник
2

Вы можете использовать ES6 Mapдля этого использования, Object.fromEntriesчтобы преобразовать mapобратно в Object.

Для получения дополнительной информации о карте

let languagePack=
[{
  'key': 'Username',
  'value': 'Benutzername',
  'group': 'default'
},
{
  'key': 'Password',
  'value': 'Passwort',
  'group': 'default'
}];

let map = new Map();

languagePack.forEach((val)=>{
  map.set(val.key, val.value);
})
languagePack = Object.fromEntries(map);
console.log(languagePack);

Акшай Банде
источник