Cambiar matriz en javascript en objeto más simple

17

Tengo un JSON simple con una matriz que contiene más objetos, etc. como este:

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

Pero lo que realmente quiero es un objeto como este:

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

Entonces, quiero reducir la matriz a simples pares clave-valor que están dentro de una matriz o incluso un objeto (las claves son únicas). ¿Alguien tiene una idea de cómo reducir esto con algunas de estas geniales funciones de matriz? Solo se me ocurrió algo así como un para cada uno y construir la propiedad del objeto "a mano" para la propiedad, pero recuerdo que había algunas cosas interesantes para la matriz como 'reducir', el operador de propagación (...), el mapa, cada, algunos, etc.

Lo probé con algo como:

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

Pero eso solo me dio un mensaje de error TypeError: Invalid attempt to destructure non-iterable instance

Editar: Las tres respuestas funcionan perfectamente bien. Gracias.

Marcel Grüger
fuente
2
Posible duplicado de Cómo formatear la lista de matrices a json
adiga
El groupserá ignorado?
Bergi
Sí, el grupo puede ser ignorado, solo fue una idea de mi compañero de trabajo usar la misma clave en diferentes pantallas con diferentes traducciones, pero no puedo encontrarle ningún uso real. Pero esa es otra pregunta para mucho más tarde :)
Marcel Grüger

Respuestas:

11

Básicamente, debe usar en forEachlugar de la mapfunción y luego puede construir ese objeto a cualquier clave, par de valores que desee mantener.

Pruebe esto, resolverá su problema.

var temp = {};

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

console.log(temp)

Nota: Aquí no estamos usando mapporque queremos devolver un objeto, no una matriz, por lo que podemos usar la reducefunción aquí para hacerlo, pero pensé que esto sería simple y fácil de entender lo que queremos y qué estamos haciendo aquí.

ma_dev_15
fuente
10

Puede usar la reducefunción de JavaScript para crear un objeto vacío y poner cada clave y valor en él.

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

Editar: Buena sugerencia de Donny Verduijn . Puede usar es6 desestructuración para escribir la función más corta.

const newData = data.reduce((acc, { key, value }) => ({ ...acc, [key]: value }), {});
Maxime Girou
fuente
3
Si desea utilizar la sintaxis ES6, también puede implementar la función de reducción de esta manera(acc, { key, value }) => ({ ...acc, [key]: value })
Donny Verduijn
1
Además, puede usar el operador de coma para evitar la devolución:const newData = data.reduce((acc, row) => (acc[row.key] = row.value, acc), {});
ElChiniNet
44
Solo como curiosidad. Hace algún tiempo estaba probando el rendimiento del operador de propagación para desestructurar objetos, e incluso si es cierto que a veces mejora la legibilidad del código, tiene un alto costo: measurethat.net/Benchmarks/Show/6194/5/ ...
ElChiniNet
@ElChiniNet El caso de prueba que vinculó es sobre la distribución de la matriz, no sobre la distribución de objetos. (Pero sí, propagarse repetidamente en un nuevo objeto es mucho más lento que mutar un solo objeto)
Bergi
1
@ Bergi, aquí tienes una comparación de este código específico: measurethat.net/Benchmarks/Show/6318/0/…
ElChiniNet
6

utilizar con Array#mapsu crear la clave y el valor como objeto y el Object.assignvalor de matriz encubierta para objetar

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

Puede usar ES6 Mappara ese uso Object.fromEntriespara mapvolver a convertir Object.

Para más información sobre 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
fuente