Alterar matriz em javascript para objeto mais simples

17

Eu tenho um JSON simples com uma matriz que contém outros objetos, etc. como este:

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

Mas o que eu realmente quero é um objeto como este:

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

Então, quero reduzir a matriz para pares simples de valor-chave que estão dentro de uma matriz ou mesmo de um objeto (as chaves são únicas). Alguém tem uma idéia de como reduzir isso com algumas dessas funções de matriz legal? Eu só criei algo como um para cada um e construí o objeto "à mão" propriedade para propriedade, mas lembro que havia algumas coisas legais para matriz como 'reduzir', o operador de propagação (...), mapa, todos, alguns etc.

Eu tentei com algo como:

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

Mas isso só me deu uma mensagem de erro TypeError: Invalid attempt to destructure non-iterable instance

Edit: Todas as três respostas estão funcionando perfeitamente. Obrigado.

Marcel Grüger
fonte
2
Possível duplicata Como lista de matriz formato para json
Adiga
O groupdeve ser ignorado?
Bergi 15/11/19
Sim, o grupo pode ser ignorado, foi apenas uma ideia do meu colega de trabalho usar a mesma chave em telas diferentes com traduções diferentes, mas não consigo encontrar nenhum uso real para isso. Mas isso é outra questão para mais tarde :)
Marcel gruger

Respostas:

11

Basicamente, você precisa usar em forEachvez da mapfunção e, em seguida, criar esse objeto com qualquer par de chaves e valores que deseja manter.

Tente isso, ele resolverá o seu problema.

var temp = {};

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

console.log(temp)

Nota: Aqui não estamos usando mapporque queremos retornar um objeto e não uma matriz, portanto, podemos usar a reducefunção aqui para fazê-lo, mas achei que seria simples e fácil entender o que queremos e o que estamos fazendo aqui.

ma_dev_15
fonte
10

Você pode usar a reducefunção javascript para criar um objeto vazio e colocar cada chave e valor nele.

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

Edit: Nice sugerir Donny Verduijn . Você pode usar es6 destructuring para escrever a função mais curta.

const newData = data.reduce((acc, { key, value }) => ({ ...acc, [key]: value }), {});
Maxime Girou
fonte
3
Se você gosta de usar ES6 sintaxe que você também pode implementar a função de reduzir desta forma(acc, { key, value }) => ({ ...acc, [key]: value })
Donny Verduijn
11
Além disso, você pode usar o operador vírgula para evitar o retorno:const newData = data.reduce((acc, row) => (acc[row.key] = row.value, acc), {});
ElChiniNet 15/11/19
4
Apenas como uma curiosidade. Algum tempo atrás, eu estava testando o desempenho do operador de propagação para destruir objetos e, mesmo que às vezes melhore a legibilidade do código, ele tem um alto custo: Measurethat.net/Benchmarks/Show/6194/5/ ...
ElChiniNet 15/11/19
@ElChiniNet O caso de teste que você vinculou é sobre propagação de matriz, não propagação de objeto. (Mas sim, repetidamente se espalhando em um novo objeto é muito mais lento do que mutação de um único objeto)
Bergi
11
@Bergi, aqui você tem uma comparação deste código específico: measurethat.net/Benchmarks/Show/6318/0/...
ElChiniNet
6

use com Array#mapele criar a chave e o valor como objeto e o Object.assignvalor da matriz secreta para o objeto

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
fonte
2

Você pode usar o ES6 Mappara esse uso Object.fromEntriespara converter mapnovamente em Object.

Para mais informações sobre o Mapa

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

Akshay Bande
fonte