Cómo convertir un objeto {} en una matriz [] de pares clave-valor en JavaScript

244

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 una matriz de pares clave-valor como este:

[[1,5],[2,7],[3,0],[4,0]...].

¿Cómo puedo convertir un objeto en una matriz de pares clave-valor en JavaScript?

Soptareanu Alex
fuente

Respuestas:

430

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(function(key) {
  return [Number(key), obj[key]];
});

console.log(result);

Nenad Vracar
fuente
77
@blvckasvp ¿Estás usando números como claves? De lo contrario, cuando intente convertir su clave en un número, fallará y volverá NaNen su lugar. Si desea usar cadenas como sus claves, cambie el retorno de [Number(key), obj[key]]a [key, obj[key]]o use Object.entriescomo sugirió @Pila en su respuesta
scottbot95
123

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} 
Object.entries(obj);

Llamar entries, como se muestra aquí, devolverá [key, value]pares, como solicitó el autor de la pregunta.

Alternativamente, puede llamar Object.values(obj), lo que devolvería solo valores.

Pila
fuente
66
Estimados desarrolladores, comprueben la tabla de compatibilidad de ECMA antes de adoptar estas funciones agradables que solo son compatibles con los navegadores lanzados hace unos minutos.
andreszs
8
@andreszs Vea la tabla ¿Puedo usar? Si no le importa abandonar el soporte de IE (y en 2019, espero que no lo haga), entonces está bastante listo. FF 47 es de junio de 2016 y Chrome 54 es de octubre del mismo año, Edge 14 de agosto. No exactamente hace unos minutos.
Kyll
FYI: Object.entries devolverá [clave, valor], pero la clave será una cadena, el valor será diferente.
SHAHBAZ
62

Object.entries()devuelve una matriz cuyos elementos son matrices correspondientes a los [key, value]pares de propiedades enumerables que se encuentran directamente sobre object. El orden de las propiedades es el mismo que el dado al recorrer manualmente los valores de propiedad del objeto.

- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries#Description

La Object.entriesfunción devuelve casi el resultado exacto que está solicitando, excepto que las teclas 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 necesita que las claves sean números, puede asignar el resultado a una nueva matriz con una función de devolución de llamada que reemplace la clave en cada par con un número forzado.

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

Utilizo una función de flecha y Object.assignpara la devolución de llamada del mapa en el ejemplo anterior para poder mantenerla en una instrucción aprovechando el hecho de que Object.assigndevuelve el objeto al que se está asignando, y el valor de retorno de una sola función de flecha de instrucción 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 de mapa podría acortarse a:

entry => [ +entry[0], entry[1] ]

Sin embargo, eso crearía una nueva matriz para cada par clave-valor, en lugar de modificar la matriz existente en su lugar, duplicando la cantidad de matrices de pares clave-valor creadas. Si bien la matriz de entradas originales aún está accesible, no se recolectarán basura ni sus entradas.

Ahora, aunque el uso de nuestro método in situ todavía utiliza dos matrices que contienen los pares clave-valor (las matrices de entrada y de salida), el número total de matrices solo cambia en uno. Las matrices de entrada y salida en realidad no están llenas de matrices, sino que las referencias a las matrices y esas referencias ocupan una cantidad insignificante de espacio en la memoria.

  • La modificación de cada par clave-valor en el lugar da como resultado una cantidad insignificante de crecimiento de memoria, pero requiere escribir algunos caracteres más.
  • La creación de una nueva matriz para cada par clave-valor da como resultado la duplicación de la cantidad de memoria requerida, pero requiere escribir algunos caracteres menos.

Puede ir un paso más allá y eliminar el crecimiento por completo modificando la matriz de entradas en el lugar en lugar de asignarla a una nueva matriz:

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


fuente
1
Me gusta el enfoque funcional. Como alternativa más corta:Object.entries(obj).map(e => [+e[0], e[1]]);
Travis Clarke
21

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};
  • Solo obteniendo ciegamente los valores en una matriz, no importa 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 una matriz:

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 teclas 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]]

  • Usar la propiedad del objeto como clave para una nueva matriz (podría crear matrices dispersas):

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 de la matriz según el valor de las claves. A veces, este podría ser el comportamiento deseado (a veces no). Pero la ventaja ahora es que los valores están indexados en la ranura de matriz correcta, esencial y trivial para realizar búsquedas en ella.

  • Mapa en lugar de matriz

Finalmente (no es parte de la pregunta original, pero para completar), si necesita buscar fácilmente utilizando la clave o el valor, pero no desea matrices dispersas, sin duplicados y sin reordenamiento sin la necesidad de convertir a claves numéricas ( incluso puede acceder a claves muy complejas), entonces la matriz (u objeto) no es lo que necesita. RecomendaréMap lugar:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

let r=new Map(Object.entries(obj));
r.get("4"); //6
r.has(8); //true
CarlosH.
fuente
2
El cuarto punto en adelante es completamente irrelevante para la pregunta, y el resto de su respuesta solo resume las tres respuestas principales aquí. Esta respuesta no aporta nada a la discusión que aún no estaba aquí o que no es completamente irrelevante.
Sí, como dice la primera línea, este es un resumen de las respuestas, luego actualícelas para usar las técnicas modernas de ES6 en lugar de las funciones completas. La cuarta respuesta es útil cuando está moviendo matrices JSON desde un lenguaje que admite matrices asociativas (por ejemplo, PHP).
CarlosH.
Todos los métodos proporcionados aquí ya se han proporcionado en su forma simple en dos de las tres respuestas principales, no están en funciones, por lo que no sé de qué se trata allí. Hasta el 4, como dije, es completamente irrelevante para la pregunta formulada. Puede ser relevante para una pregunta diferente, pero no esta. Independientemente, JSON es JSON ya sea que se haya creado usando PHP, JavaScript o Haskell.
18

Otra solución más si Object.entriesno funciona para usted.

const obj = {
      '1': 29,
      '2': 42
    };
const arr = Array.from(Object.keys(obj), k=>[`${k}`, obj[k]]);
console.log(arr);

bigh_29
fuente
1
Esto funcionó para mí. Experimenté un problema en el que la importación de JSON agregaba índices que hacían imposible usar el bucle Angulars ngFor. Esto eliminó los índices mientras preservaba la estructura.
RAC
@RAC +1 para usar "índices" en lugar de "índices". ¡Fuera las tradiciones inglesas arcaicas (es decir, arbitrarias y desviadas sin sentido)!
Venryx
12

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

violín

Nageshwar Reddy Pandem
fuente
No estoy seguro de por qué esto fue rechazado, funcionó perfectamente bien
sMyles
1
No voté en contra, pero tenga en cuenta que la .map((value)=>(value))porción no tiene sentido, solo devuelve una matriz de entrada exactamente equivalente a la obtenida de la Object.entries(obj)llamada.
Venryx el
8

Uso Object.keysy Array#mapmétodos.

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

Pranav C Balan
fuente
7

Use Object.entriespara obtener cada elemento del Objeto en key & valueformato, luego a maptravés de ellos de esta manera:

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á seguro de que las teclas estarán en orden progresivo , puede usar Object.valuesy Array#maphacer 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);

Barba Negra
fuente
5

Si está usando lodash, podría ser tan simple como esto:

var arr = _.values(obj);
Adam Boostani
fuente
5

Con lodash, además de la respuesta proporcionada anteriormente, también puede tener la clave en la matriz de salida.

Sin las claves de objeto en la matriz de salida

para:

const array = _.values(obj);

Si obj es el siguiente:

{ art”: { id: 1,  title: aaaa }, fiction”: { id: 22,  title: 7777”} }

Entonces la matriz será:

[ { id: 1, title: aaaa }, { id: 22, title: 7777 } ]

Con las claves de objeto en la matriz de salida

Si escribes en su lugar ('género' es una cadena que eliges):

const array= _.map(obj, (val, id) => {
    return { ...val, genre: key };
  });

Conseguirás:

[ 
  { id: 1, title: aaaa , genre: art”}, 
  { id: 22, title: 7777”, genre: fiction }
]
Yossi
fuente
4

Sugeriría esta solución más simple de usar Object.entries()

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

Pila de ironía
fuente
1

Puede usarlo Object.values([]), es posible que necesite este polyfill si aún no lo hace:

const objectToValuesPolyfill = (object) => {
  return Object.keys(object).map(key => object[key]);
};
Object.values = Object.values || objectToValuesPolyfill;

https://stackoverflow.com/a/54822153/846348

Entonces puedes simplemente hacer:

var object = {1: 'hello', 2: 'world'};
var array = Object.values(object);

Solo recuerde que las matrices en js solo pueden usar teclas numéricas, por lo que si usó algo más en el objeto, esas se convertirán en `0,1,2 ... x``

Puede ser útil eliminar duplicados, por ejemplo, si tiene una clave única.

var obj = {};
object[uniqueKey] = '...';
OZZIE
fuente
0

Usar para en

var obj = { "10":5, "2":7, "3":0, "4":0, "5":0, "6":0, "7":0,
            "8":0, "9":0, "10":0, "11":0, "12":0 };

var objectToArray = function(obj) {
    var _arr = [];

    for (var key in obj) {
        _arr.push([key, obj[key]]);
    }
    return _arr;
}

console.log(objectToArray(obj));
wkyniston
fuente
0

Objeto de conversión recursivo a matriz

function is_object(mixed_var) {
    if (mixed_var instanceof Array) {
        return false;
    } else {
        return (mixed_var !== null) && (typeof( mixed_var ) == 'object');
    }
}


function objectToArray(obj) {
    var array = [], tempObject;
    for (var key in obj) {

        tempObject = obj[key];

        if (is_object(obj[key])) {
            tempObject = objectToArray(obj[key]);
        }
        array[key] = tempObject;
    }
    return array;
}
Marina Lebedeva
fuente
0

Podemos cambiar el número a tipo de cadena para clave como a continuación:

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(function(key) {
  return [String(key), obj[key]];
});
    
console.log(result);

Nagnath Mungade
fuente
0

Esta es mi solución, tengo el mismo problema y parece que esta solución funciona para mí.

yourObj = [].concat(yourObj);
Qui-Gon Jinn
fuente
0

Esta es mi implementación básica básica:

let 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 objectToArray = obj => {
      let sol = [];
      for (key in obj) {
        sol.push([key, obj[key]]);
      }
      return sol;
    };

objectToArray(obj)
Ketan Ramteke
fuente
0

Solución simple

``

var result = Object.keys(records).map(function (value) {
         return { [value]: records[value] };
});
console.log(result);

Folorunso
fuente