Come convertire un oggetto {} in un array [] di coppie chiave-valore in JavaScript


244

Voglio convertire un oggetto come questo:

{"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}

in un array di coppie chiave-valore come questo:

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

Come posso convertire un oggetto in una matrice di coppie chiave-valore in JavaScript?

Risposte:


430

Puoi usare Object.keys()e map()per fare questo

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


7
@blvckasvp Stai usando i numeri come chiavi? In caso contrario, quando tenta di convertire la chiave in un numero, fallirà e tornerà NaNinvece. Se si desidera utilizzare stringhe come le chiavi, modificare il ritorno da [Number(key), obj[key]]a [key, obj[key]]o utilizzare il Object.entriescome @Pila suggerito nella loro risposta
scottbot95

123

Il modo migliore è fare:

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

La chiamata entries, come mostrato qui, tornerà[key, value] coppie, come richiesto dal richiedente.

In alternativa, è possibile chiamare Object.values(obj), che restituirebbe solo valori.


6
Cari sviluppatori, controllate la tabella di compatibilità ECMA prima di adottare queste simpatiche funzioni compatibili solo con i browser rilasciati pochi minuti fa.
andreszs,

8
@andreszs Vedi Can I Use table, se non ti dispiace far cadere il supporto IE (e nel 2019, spero per la tua sanità mentale che non lo fai davvero) allora sei praticamente bravo ad andare. FF 47 è di giugno 2016 e Chrome 54 è di ottobre dello stesso anno, Edge 14 agosto. Non esattamente minuti fa.
Kyll

Cordiali saluti: Object.entries restituirà [chiave, valore], ma la chiave sarà una stringa, il valore sarà diverso.
SHAHBAZ,

62

Object.entries()restituisce un array i cui elementi sono array corrispondenti alle enumerabili [key, value]coppie di proprietà trovate direttamente su object. L'ordinamento delle proprietà è uguale a quello fornito eseguendo il ciclo manualmente sui valori delle proprietà dell'oggetto.

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

La Object.entriesfunzione restituisce quasi l'output esatto che stai chiedendo, tranne i tasti sono stringhe anziché numeri.

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

Se è necessario che i tasti siano numeri, è possibile mappare il risultato su un nuovo array con una funzione di callback che sostituisce il tasto in ciascuna coppia con un numero forzato da esso.

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 funzione freccia e Object.assignper il callback della mappa nell'esempio sopra in modo da poterlo conservare in un'istruzione sfruttando il fatto che Object.assignrestituisce l'oggetto a cui è assegnato, e il valore restituito di una singola istruzione freccia è il risultato dell'istruzione.

Ciò equivale a:

entry => {
    entry[0] = +entry[0];
    return entry;
}

Come menzionato da @TravisClarke nei commenti, la funzione della mappa potrebbe essere abbreviata in:

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

Tuttavia, ciò creerebbe un nuovo array per ciascuna coppia chiave-valore, invece di modificare l'array esistente in atto, raddoppiando quindi la quantità di array di coppie chiave-valore create. Mentre l'array di voci originale è ancora accessibile, esso e le sue voci non verranno raccolte in modo inutile.

Ora, anche se il nostro metodo sul posto utilizza ancora due array che contengono le coppie chiave-valore (array di input e output), il numero totale di array cambia solo di uno. Le matrici di input e output non sono effettivamente piene di matrici, ma piuttosto i riferimenti alle matrici e quei riferimenti occupano una quantità trascurabile di spazio nella memoria.

  • La modifica di ogni coppia chiave-valore sul posto comporta una quantità trascurabile di crescita della memoria, ma richiede la digitazione di alcuni caratteri in più.
  • La creazione di un nuovo array per ciascuna coppia chiave-valore comporta il raddoppio della quantità di memoria richiesta, ma richiede la digitazione di alcuni caratteri in meno.

È possibile fare un ulteriore passo avanti ed eliminare del tutto la crescita modificando la matrice di voci sul posto anziché mappandola su una nuova matrice:

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


1
Mi piace l'approccio funzionale. Come alternativa più breve:Object.entries(obj).map(e => [+e[0], e[1]]);
Travis Clarke,

21

Ricapitolando alcune di queste risposte ora nel 2018, dove ES6 è lo standard.

A partire dall'oggetto:

let const={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
  • Basta ottenere ciecamente i valori su un array, non preoccuparsi delle chiavi:

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]

  • Semplice ottenere le coppie su un array:

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

  • Come il precedente, ma con tasti numerici su ciascuna coppia:

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

  • Utilizzo della proprietà dell'oggetto come chiave per un nuovo array (potrebbe creare array sparsi):

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]

Quest'ultimo metodo, potrebbe anche riorganizzare l'ordine dell'array in base al valore delle chiavi. A volte questo potrebbe essere il comportamento desiderato (a volte no). Ma il vantaggio ora è che i valori sono indicizzati nello slot di array corretto, essenziale e banale per fare ricerche su di esso.

  • Mappa invece di matrice

Infine (non parte della domanda originale, ma per completezza), se devi cercare facilmente usando la chiave o il valore, ma non vuoi matrici sparse, nessun duplicato e nessun riordino senza la necessità di convertire in chiavi numeriche ( può persino accedere a chiavi molto complesse), quindi l'array (o l'oggetto) non è ciò di cui hai bisogno. Raccomanderò Mapinvece:

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

2
Il quarto punto e in avanti è completamente irrilevante per la domanda, e il resto della tua risposta sta semplicemente riassumendo le prime tre risposte qui. Questa risposta non porta nulla alla discussione che non era già qui o non è del tutto irrilevante.

Sì, come lo stato della prima riga, questo è un riepilogo delle risposte, quindi aggiornale per utilizzare le moderne tecniche ES6 anziché le funzioni complete. La quarta risposta è utile quando si spostano gli array JSON da un linguaggio che supporta gli array associativi (ad esempio PHP).
CarlosH.

Tutti i metodi forniti qui sono già stati forniti nella loro forma semplice in due delle prime tre risposte, non sono in funzione, quindi non so di cosa ti occupi lì. Per quanto riguarda il 4, come ho detto, è del tutto irrilevante per la domanda posta. Potrebbe essere rilevante per una domanda diversa, ma non questa. Indipendentemente da ciò, JSON è JSON indipendentemente dal fatto che sia stato creato utilizzando PHP, JavaScript o Haskell.

18

Ancora un'altra soluzione se Object.entriesnon funzionerà per te.

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


1
Questo ha funzionato per me. Ho riscontrato un problema in cui l'importazione di JSON ha aggiunto indici che hanno reso impossibile utilizzare Angulars ngFor loop. Ciò ha rimosso gli indici preservando la struttura.
RAC,

@RAC +1 per l'utilizzo di "indici" anziché "indici". Tradizioni inglesi iniziate, arcaiche (cioè arbitrarie e insignificanti)!
Venryx

12

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

violino


Non sono sicuro del motivo per cui questo è stato downvoted, ha funzionato perfettamente
sMyles il

1
Non ho effettuato il downgrade, ma nota che la .map((value)=>(value))parte non ha senso: restituisce semplicemente un array di entrata esattamente equivalente a quello ottenuto dalla Object.entries(obj)chiamata.
Venryx,

8

Uso Object.keyse Array#mapmetodi.

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


7

Utilizzare Object.entriesper ottenere ogni elemento di Object in key & valueformato, quindi mapattraverso di essi in questo modo:

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

Ma, se sei certo che le chiavi saranno in ordine progressivo, puoi usare Object.valuese Array#mapfare qualcosa del genere:

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


5

Se stai usando lodash, potrebbe essere semplice come questo:

var arr = _.values(obj);

5

Con lodash, oltre alla risposta fornita sopra, puoi anche avere la chiave nell'array di output.

Senza le chiavi dell'oggetto nell'array di output

per:

const array = _.values(obj);

Se obj è il seguente:

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

Quindi l'array sarà:

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

Con le chiavi dell'oggetto nell'array di output

Se invece scrivi ('genere' è una stringa che scegli):

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

Otterrete:

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

4

Vorrei suggerire questa soluzione più semplice da usare 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);


1

Puoi usare Object.values([]), potresti aver bisogno di questo polyfill se non lo fai già:

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

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

Quindi puoi semplicemente fare:

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

Ricorda solo che le matrici in js possono usare solo tasti numerici, quindi se hai usato qualcos'altro nell'oggetto, questi diventeranno `0,1,2 ... x``

Può essere utile rimuovere duplicati, ad esempio se si dispone di una chiave univoca.

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

0

Utilizzare per in

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

0

Converti oggetto ricorsivo in array

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

0

Possiamo cambiare il numero in tipo stringa per chiave come di seguito:

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


0

Questa è la mia soluzione, ho lo stesso problema e sembra che questa soluzione funzioni per me.

yourObj = [].concat(yourObj);

0

Questa è la mia semplice implementazione barebone:

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)

0

Soluzione semplice

`

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


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.