Cómo convertir un Objeto {} en un Array [] de pares clave-valor en JavaScript
Quiero convertir un objeto como este:
{"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
en un arreglo de pares clave-valor como este:
[[1,5],[2,7],[3,0],[4,0]...].
¿Cómo puedo convertir un objeto en un arreglo de pares clave-valor en JavaScript?
Respuesta #1
Puedes usar Object.keys() y map() para hacer esto
var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result = Object.keys(obj).map((key) => [key, obj[key]]);
console.log(result);Respuesta #2
La mejor manera es hacer:
var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result = Object.entries(obj);
console.log(result);Llamar a entries, como se muestra aquí, devolverá pares [clave, valor], como solicitó el llamador.
Alternativamente, podrías llamar a Object.values(obj), lo cual devolvería solo los valores.
Respuesta #3
Object.entries()devuelve un arreglo cuyos elementos son arreglos correspondientes a los pares de propiedades enumerables[clave, valor]encontrados directamente enobject. El orden de las propiedades es el mismo que el que se obtiene al recorrer manualmente los valores de las propiedades del objeto.- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries#Description
La función Object.entries devuelve casi exactamente la salida que estás pidiendo, excepto que las claves son cadenas en lugar de números.
const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};
console.log(Object.entries(obj));Si necesitas que las claves sean números, podrías mapear el resultado a un nuevo arreglo con una función de devolución de llamada que reemplace la clave en cada par con un número convertido a partir de ella.
const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};
const toNumericPairs = input => {
const entries = Object.entries(input);
return entries.map(entry => Object.assign(entry, { 0: +entry[0] }));
}
console.log(toNumericPairs(obj));Uso una función flecha y Object.assign para el callback del map en el ejemplo anterior para poder mantenerlo en una sola instrucción aprovechando el hecho de que Object.assign devuelve el objeto al que se le asigna, y el valor de retorno de una función flecha de instrucción única es el resultado de la instrucción.
Esto es equivalente a:
entry => {
entry[0] = +entry[0];
return entry;
}
Como mencionó @TravisClarke en los comentarios, la función map podría abreviarse a:
entry => [ +entry[0], entry[1] ]
Sin embargo, eso crearía un nuevo arreglo para cada par clave-valor, en lugar de modificar el arreglo existente en su lugar, duplicando así la cantidad de arreglos de pares clave-valor creados. Aunque el arreglo de entradas original todavía es accesible, él y sus entradas no serán recolectados por el recolector de basura.
Ahora, aunque usar nuestro método in situ todavía utiliza dos arreglos que contienen los pares clave-valor (los arreglos de entrada y de salida), el número total de arreglos solo cambia en uno. Los arreglos de entrada y salida en realidad no están llenos de arreglos, sino de referencias a arreglos y esas referencias ocupan una cantidad insignificante de espacio en la memoria.
- Modificar cada par clave-valor en el lugar resulta en una cantidad insignificante de crecimiento de memoria, pero requiere escribir algunos caracteres más.
- Crear un nuevo arreglo para cada par clave-valor resulta en duplicar la cantidad de memoria requerida, pero requiere escribir unos pocos caracteres menos.
Podrías ir un paso más allá y eliminar el crecimiento por completo modificando el arreglo de entradas en el lugar en lugar de mapearlo a un nuevo arreglo:
const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};
const toNumericPairs = input => {
const entries = Object.entries(obj);
entries.forEach(entry => entry[0] = +entry[0]);
return entries;
}
console.log(toNumericPairs(obj));Respuesta #4
Para recapitular algunas de estas respuestas ahora en 2018, donde ES6 es el estándar.
Comenzando con el objeto:
let const={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
- Simplemente obteniendo los valores de un arreglo a ciegas, sin importar las claves:
const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.values(obj));
//[9,8,7,6,5,4,3,2,1,0,5]- Simple obtener los pares en un arreglo:
const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj));
//[["1",9],["2",8],["3",7],["4",6],["5",5],["6",4],["7",3],["8",2],["9",1],["10",0],["12",5]]- Igual que el anterior, pero con claves numéricas en cada par:
const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj).map(([k,v])=>[+k,v]));
//[[1,9],[2,8],[3,7],[4,6],[5,5],[6,4],[7,3],[8,2],[9,1],[10,0],[12,5]]- Usando la propiedad del objeto como clave para un nuevo arreglo (podría crear arreglos dispersos):
const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj).reduce((ini,[k,v])=>(ini[k]=v,ini),[]));
//[undefined,9,8,7,6,5,4,3,2,1,0,undefined,5]Este último método, también podría reorganizar el orden del arreglo dependiendo del valor de las claves. A veces esto podría ser el comportamiento deseado (otras veces no). Pero la ventaja ahora es que los valores están indexados en la posición correcta del arreglo, esencial y trivial para hacer búsquedas en él.
- Mapa en lugar de Arreglo
Finalmente (no es parte de la pregunta original, pero para completar), si necesitas buscar fácilmente usando la clave o el valor, pero no quieres arrays dispersos, duplicados y reordenamiento sin necesidad de convertir a claves numéricas (incluso puedes acceder a claves muy complejas), entonces un array (u objeto) no es lo que necesitas. Recomendaría Map en su lugar:
https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Map
let r=new Map(Object.entries(obj));
r.get("4"); //6
r.has(8); //true
Respuesta #5
En Ecmascript 6,
var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};
var res = Object.entries(obj);
console.log(res);
var obj = {
"1": 5,
"2": 7,
"3": 0,
"4": 0,
"5": 0,
"6": 0,
"7": 0,
"8": 0,
"9": 0,
"10": 0,
"11": 0,
"12": 0
};
var res = Object.entries(obj);
console.log(res);Respuesta #6
Otra solución más si Object.entries no funciona para ti.
const obj = {
'1': 29,
'2': 42
};
const arr = Array.from(Object.keys(obj), k=>[`${k}`, obj[k]]);
console.log(arr);Respuesta #7
Usa los métodos Object.keys y Array#map.
var obj = {
"1": 5,
"2": 7,
"3": 0,
"4": 0,
"5": 0,
"6": 0,
"7": 0,
"8": 0,
"9": 0,
"10": 0,
"11": 0,
"12": 0
};
// get all object property names
var res = Object.keys(obj)
// iterate over them and generate the array
.map(function(k) {
// generate the array element
return [+k, obj[k]];
});
console.log(res);Respuesta #8
Usa Object.entries para obtener cada elemento del objeto en formato clave & valor, luego map a través de ellos así:
var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var res = Object.entries(obj).map(([k, v]) => ([Number(k), v]));
console.log(res);Pero, si estás seguro de que las claves estarán en orden progresivo, puedes usar Object.values y Array#map para hacer algo como esto:
var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};
// idx is the index, you can use any logic to increment it (starts from 0)
let result = Object.values(obj).map((e, idx) => ([++idx, e]));
console.log(result);