Crear objeto a partir de una matriz

83

Quiero crear un objeto de la lista de matriz. Tengo una matriz que es dinámica que se supone que se verá así:

var dynamicArray = ["2007", "2008", "2009", "2010"];

y con algo de javascript es6 quiero hacer un objeto como este:

const obj = {
    2007: {
        x: width / 5,
        y: height / 2
    },
    2008: {
        x: (2 / 5) * width,
        y: height / 2
    },
    2009: {
        x: (3 / 5) * width,
        y: height / 2
    },
    2010: {
        x: (4 / 5) * width,
        y: height / 2
    }
}

no se preocupe por los objetos internos, pero solo quería una estructura de fabricación como esta:

 obj = {
      2007: ...,
      2008: ...,
      ...
    }

Por favor ayuda, gracias.

Hussain Dehgamwala
fuente
2
Bueno. Que has probado ¿Dónde estás atrapado? ¿Qué investigación has hecho? ¿Ha mirado esto , por ejemplo?
TJ Crowder

Respuestas:

203

Simplemente

 const obj = {};

 for (const key of yourArray) {
      obj[key] = whatever;
 }

o si prefieres el estilo "funcional":

 const obj = yourArray.reduce((o, key) => Object.assign(o, {[key]: whatever}), {});

utilizando el operador de propagación de objetos moderno:

const obj = yourArray.reduce((o, key) => ({ ...o, [key]: whatever}), {})

Ejemplo:

[
  { id: 10, color: "red" },
  { id: 20, color: "blue" },
  { id: 30, color: "green" }
].reduce((acc, cur) => ({ ...acc, [cur.color]: cur.id }), {})

Salida:

{red: 10, blue: 20, green: 30}

Así es como funciona:

reducese inicializa con un objeto vacío (vacío {}al final), por lo tanto, las variables de primera iteración son acc = {} cur = { id: 10, color: "red" }. La función devuelve un objeto; es por eso que el cuerpo de la función está entre paréntesis => ({ ... }). El operador de propagación no hace nada en la primera iteración, por lo que red: 10se establece como primer elemento.

En la segunda iteración, las variables son acc = { red: 10 } cur = { id: 20, color: "blue" }. Aquí el operador de spread se expande acc y la función regresa { red: 10, blue: 20 }.

Tercera iteración acc = { red: 10, blue: 20 } cur = { id: 30, color: "green" }, por lo que cuando accse extiende dentro del objeto, nuestra función devuelve el valor final.

georg
fuente
1
¡Gracias! Funcionó según lo requerido. Nunca supe de la array.reducefunción.
Hussain Dehgamwala
1
Si prefieres el estilo funcional, y yo lo hago, deberías usar const. En realidad, deberías usarlo independientemente. Además, si tiene acceso a la sintaxis de ES Next rest / spread (por ejemplo, a través de TypeScript o Babel), puede escribir const obj = yourArray.reduce((o, key) => ({ ...o, [key]: whatever}), {})e incluso evitar mutar la semilla: p
Aluan Haddad
1
@AluanHaddad: buena sugerencia, convirtió la publicación a CW, no dude en editar.
georg
({... o, [clave]: candidatoDoc [clave]}) .. donde candidatoDoc es un pojo. Quiero tomar solo los valores que están definidos en CandidatoDoc. Pero estoy confundido con el paréntesis, parece que no puedo obtener una 'devolución' o una declaración if para que funcione. ¿Podría indicarme la dirección correcta, no tener miedo de leer la documentación?
2018
1
@cameck: gracias, la publicación es CW, no dude en editarla.
georg
33

El nuevo Object.fromEntries, de ECMAScript 2019, hace que sea aún más fácil transformar valores de una matriz en claves en un objeto como sigue

const dynamicArray = ["2007", "2008", "2009", "2010"];
const obj = Object.fromEntries(
  dynamicArray.map(year => [year, {
    something: "based",
    on: year
  }])
)

console.log(obj)

Abderrahmane TAHRI JOUTI
fuente
17

en js con la función de reducción es6 para la matriz, lo hago así

let x = [1,2,3]
let y = x.reduce((acc, elem) => {
  acc[elem] = elem // or what ever object you want inside
  return acc
}, {})
console.log(y) // {1:1, 2:2, 3:3}
Ralexrdz
fuente
3
aún más corto:[1, 2, 3].reduce((x, y)=>(x[y] = 1, x), {})
exebook
4
var keys = ['key1', 'key2', 'key3']

var object = Object.assign({}, ...Object.entries({...keys}).map(([a,b]) => ({ [b]: 'someValue' })))
console.log(object)

Esto producirá

{ key1: 'someValue', key2: 'someValue', key3: 'someValue' }
Alok Singh Mahor
fuente
0

Descubrí que en realidad se puede usar Object.assign()directamente con el operador de propagación. No es necesario introducir más complejidad con una función reduceo map.

Simplemente hazlo Object.assign(...yourArray, {})y obtendrás el resultado deseado. Si, en cambio, desea fusionar su matriz de objetos en otro objeto, también puede llamar Object.assign(...yourArray, yourObject)y también funcionará bien.

También puede usar este mismo método para fusionar dos matrices en un objeto, incluso si una de las matrices no contiene objetos sino solo valores primitivos; sin embargo, si hace esto, debe asegurarse de que al menos una de las matrices contenga solo objetos como una primitiva tomará por defecto su índice como el key, por lo que obtendrá errores si hay una clave duplicada.

Sin embargo, para el propósito de OP, no hay riesgo de errores, ya que se está fusionando con un objeto vacío, que es la forma más segura.

const arr = [
  { a: 0 },
  { c: 1 },
  { e: 2 },
];

const obj = Object.assign(...arr, {});

console.log(obj)

// Results to:
// Object { a: 0, c: 1, e: 2 }
Aasmund Berge Endresen
fuente
-4

puedes usar:

     dynamicArray.map(value => ({'key': value, 'val': 'whatever you want'}));

ingrese la descripción de la imagen aquí

jilykate
fuente
3
¡¡No como lo que quiero !!
Hussain Dehgamwala