trasforma l'oggetto in array con lodash


165

Come posso trasformare un grande objectin arraycon lodash?

var obj = {
  22: {name:"John", id:22, friends:[5,31,55], works:{books:[], films:[],}
  12: {name:"Ivan", id:12, friends:[2,44,12], works:{books:[], films:[],}
}

// transform to 
var arr = [{name:"John", id:22...},{name:"Ivan", id:12...}]

@Mritunjay Sì, perché i documenti hanno una così grande panoramica della libreria ... no. È solo un elenco esaustivo di funzioni e analizzarle ognuna potrebbe rivelarsi una perdita di tempo se non ce n'è una. La domanda è giusta.
Epirocks

Risposte:


265

Tu puoi fare

var arr = _.values(obj);

Per la documentazione vedi qui.


34
E se volessi conservare la chiave come proprietà? (in questo esempio, se la idproprietà non esisteva e si voleva crearla in base alla chiave di ciascun oggetto.
Michael Liquori

8
Potresti fare qualcosa del genere:var arr = _.values(_.mapKeys(obj, function(value, key) { value.id = key; return value; }));
Daniel Schmidt l'

1
@DanielSchmidt Non sono sicuro di cosa ho fatto di sbagliato ma quel campione ha restituito solo 1 riga per me. :( Quindi quello che ho fatto è stato spingere manualmente il returnvalore su un array come questo: const divisionsList = []; _.mapKeys(divisions, (value, key) => { divisionsList[key] = value; });apprezzerei qualsiasi commento o suggerimento per migliorare questo approccio.
JohnnyQ,

8
@JohnnyQ Penso che dovrai usare mapValues ​​invece, per esempioconst toArrayWithKey = (obj, keyAs) => _.values(_.mapValues(obj, (value, key) => { value[keyAs] = key; return value; }));
orjan,

1
@orjan Sì, in realtà l'ho capito, ho appena dimenticato di aggiornare. Grazie per questo.
JohnnyQ,

38
_.toArray(obj);

Uscite come:

[
  {
    "name": "Ivan",
    "id": 12,
    "friends": [
      2,
      44,
      12
    ],
    "works": {
      "books": [],
      "films": []
    }
  },
  {
    "name": "John",
    "id": 22,
    "friends": [
      5,
      31,
      55
    ],
    "works": {
      "books": [],
      "films": []
    }
  }
]"

1
_.toArray () Funziona bene @jivings
Syed Zain Ali

4
per ottenere solo valori è una buona opzione, ma toArraynon c'è modo di preservare le chiavi se necessario.
Koushik Chatterjee,

33

Una moderna soluzione nativa se qualcuno è interessato:

const arr = Object.keys(obj).map(key => ({ key, value: obj[key] }));

o (non IE):

const arr = Object.entries(obj).map(([key, value]) => ({ key, value }));

2
perché non soloObject.keys(obj).map(key=>({key,value: obj[key]}))
Koushik Chatterjee il

1
Mi piace il fatto che non sia nemmeno utente lodash, ben fatto signore!
HungryPipo

1
@Dominic Ora hai cambiato la tua risposta completa e l'hai presa dal mio commento, anche senza menzione (l'hai modificata). Ben fatto 👏 😁😁
Koushik Chatterjee

1
@KoushikChatterjee lo ha aggiunto di nuovo
Dominic

2
Sarebbe più utile? const arr = Object.keys(obj).map(id => ({ id, ...obj[id] })); questo porterebbe l'intero oggetto nei dati restituiti no? (usando "id" poiché il richiedente originale voleva conservare la sua chiave come supporto dell'id)
zabaat

20

Per me ha funzionato:

_.map(_.toPairs(data), d => _.fromPairs([d]));

Gira

{"a":"b", "c":"d", "e":"f"} 

in

[{"a":"b"}, {"c":"d"}, {"e":"f"}]

1
Avevo bisogno di trasformare un oggetto in un array, in modo tale che ogni chiave / valore dell'oggetto originale fosse un oggetto {chiave: valore} nell'array. _.toPairs (data) prende l'oggetto {"a": "b", "c": "d", "e": "f"} e lo restituisce come una matrice di array come [["a": " b "], [" c ":" d "], [" e ":" f "]]. _.fromPairs fa il contrario, prende un array con 2 elementi: ["a", "b"] e lo restituisce come oggetto: {"a": "b"}. Utilizzando _.map ho ripetuto l'array se gli array creati da _.toPairs per trasformarlo in un array di oggetti con l'aiuto di _.fromPairs.
NoNine,

1
Sono contento di aver scorrere verso il basso per vedere questo. La tua soluzione ha funzionato per me! Grazie!
Wale,

@NoNine Non è necessario applicare la mappa su una matrice (di matrice), è possibile applicarla direttamente sull'oggetto di input e restituire ciascuna coppia di valori chiave _.map(data, (v,k)=>({[k]: v}))vedere la mia risposta per i dettagli. _.toPairsed _fromPairsè aggiuntivo e non necessario qui.
Koushik Chatterjee,

Non è a questo che serve la domanda. perché è un po 'difficile usare il risultato poiché ogni voce contiene una chiave (che non si conosce) e di nuovo è necessario passare attraverso una logica (ad esempio Object.keys o Object.values) per ogni voce separata per ottenere il valore di ciascuno, se un giocattolo vuole preservare le chiavi, puoi creare una serie di oggetti che sono stati strutturati come[{key: 'someKey', val: 'The value'}, {....},...]
Koushik Chatterjee,

13

Esistono diversi modi per ottenere il risultato che stai cercando. Consente di suddividerli in categorie:

Solo valori ES6 :

Il metodo principale per questo è Object.values . Ma usando Object.keys e Array.map potresti anche ottenere il risultato atteso:

Object.values(obj)
Object.keys(obj).map(k => obj[k])

Chiave e valore ES6 :

Utilizzando la mappa e le proprietà dinamiche / calcolate ES6 e la destrutturazione è possibile conservare la chiave e restituire un oggetto dalla mappa.

Object.keys(obj).map(k => ({[k]: obj[k]}))
Object.entries(obj).map(([k,v]) => ({[k]:v}))

Solo valori Lodash :

Il metodo progettato per questo è _.valuestuttavia ci sono "scorciatoie" come _.mape il metodo di utilità _.toArrayche restituisce anche un array contenente solo i valori dall'oggetto. Puoi anche prendere _.mapil _.keyse ottenere i valori dall'oggetto usando la obj[key]notazione.

Nota: _.mapquando viene passato un oggetto userebbe il suo baseMapgestore che è fondamentalmente forEachsulle proprietà dell'oggetto.

_.values(obj)
_.map(obj)
_.toArray(obj)
_.map(_.keys(obj), k => obj[k])

Chiave e valore di Lodash :

// Outputs an array with [[KEY, VALUE]]
_.entries(obj)
_.toPairs(obj)

// Outputs array with objects containing the keys and values
_.map(_.entries(obj), ([k,v]) => ({[k]:v}))
_.map(_.keys(obj), k => ({[k]: obj[k]}))
_.transform(obj, (r,c,k) => r.push({[k]:c}), [])
_.reduce(obj, (r,c,k) => (r.push({[k]:c}), r), [])

Si noti che negli esempi precedenti viene utilizzato ES6 (funzioni freccia e proprietà dinamiche). È possibile utilizzare lodash _.fromPairse altri metodi per comporre un oggetto se ES6 è un problema.


12

Se vuoi che la chiave (id in questo caso) sia conservata come proprietà di ogni elemento dell'array che puoi fare

const arr = _(obj) //wrap object so that you can chain lodash methods
            .mapValues((value, id)=>_.merge({}, value, {id})) //attach id to object
            .values() //get the values of the result
            .value() //unwrap array of objects

8

Aggiornamento 2017: Object.values , lodash valori e toArray lo fanno. E per preservare la mappa delle chiavi e diffondere l'operatore gioca bene:

// import { toArray, map } from 'lodash'
const map = _.map

const input = {
  key: {
    value: 'value'
  }
}

const output = map(input, (value, key) => ({
  key,
  ...value
}))

console.log(output)
// >> [{key: 'key', value: 'value'}])
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>


7

Trasformazione di oggetti in array con semplici JavaScript ( ECMAScript-2016) Object.values:

var obj = {
    22: {name:"John", id:22, friends:[5,31,55], works:{books:[], films:[]}},
    12: {name:"Ivan", id:12, friends:[2,44,12], works:{books:[], films:[]}}
}

var values = Object.values(obj)

console.log(values);

Se vuoi anche mantenere l'uso dei tasti Object.entriese in Array#mapquesto modo:

var obj = {
    22: {name:"John", id:22, friends:[5,31,55], works:{books:[], films:[]}},
    12: {name:"Ivan", id:12, friends:[2,44,12], works:{books:[], films:[]}}
}

var values = Object.entries(obj).map(([k, v]) => ({[k]: v}))

console.log(values);


5

var arr = _.map(obj)

Puoi anche usare la _.mapfunzione (di entrambi lodashe underscore) con object, gestirà internamente quel caso, ripeterà ogni valore e chiave con l'iterato e infine restituirà un array. Infatti, puoi usarlo senza alcuna iterazione (solo _.map(obj)) se vuoi solo una matrice di valori. La parte buona è che, se hai bisogno di qualche trasformazione tra, puoi farlo in una volta sola.

Esempio:

Tuttavia, se vuoi trasformare il tuo oggetto, puoi farlo, anche se hai bisogno di conservare la chiave, puoi farlo ( _.map(obj, (v, k) => {...}) con l'argomento aggiuntivo mape poi usarlo come vuoi.

Tuttavia ci sono altre soluzioni Vanilla JS a questo (come ogni lodashsoluzione dovrebbe esserci versione JS pura) come:

  • Object.keyse poi mapli ai valori
  • Object.values (in ES-2017)
  • Object.entriese quindi mapogni coppia chiave / valore (in ES-2017)
  • for...in esegui il ciclo e usa ogni tasto per il calcolo dei valori

E molto di più. Ma poiché questa domanda è per lodash(e supponendo che qualcuno lo stia già utilizzando), non è necessario pensare molto alla versione, al supporto dei metodi e alla gestione degli errori se questi non vengono trovati.

Ci sono altre soluzioni lodash come _.values(più leggibili per scopi specifici), o ottenere coppie e quindi mappare e così via. ma nel caso in cui il codice abbia bisogno di flessibilità per poterlo aggiornare in futuro poiché è necessario preservare keyso trasformare un po 'i valori, la soluzione migliore è quella di utilizzare un singolo _.mapcome indicato in questa risposta. Questo non sarà poi così difficile come per la leggibilità.


2
Bello, molto semplice e molto conciso.
edencorbin,

5

Oggetto all'array

Di tutte le risposte penso che questa sia la migliore:

let arr = Object.entries(obj).map(([key, val]) => ({ key, ...val }))

che trasforma:

{
  a: { p: 1, q: 2},
  b: { p: 3, q: 4}
}

per:

[
  { key: 'a', p: 1, q: 2 }, 
  { key: 'b', p: 3, q: 4 }
]

Matrice all'oggetto

Per tornare indietro:

let obj = arr.reduce((obj, { key, ...val }) => { obj[key] = { ...val }; return obj; }, {})

Per tornare indietro mantenendo la chiave nel valore:

let obj = arr.reduce((obj, { key, ...val }) => { obj[key] = { key, ...val }; return obj; }, {})

Darà:

{
  a: { key: 'a', p: 1, q: 2 },
  b: { key: 'b', p: 3, q: 4 }
}

Per l'ultimo esempio puoi anche usare lodash _.keyBy(arr, 'key')o _.keyBy(arr, i => i.key).


3

Se vuoi un mapping personalizzato (come Array.prototype.map originale) di Object in un array, puoi semplicemente usare _.forEach:

let myObject = {
  key1: "value1",
  key2: "value2",
  // ...
};

let myNewArray = [];

_.forEach(myObject, (value, key) => {
  myNewArray.push({
    someNewKey: key,
    someNewValue: value.toUpperCase() // just an example of new value based on original value
  });
});

// myNewArray => [{ someNewKey: key1, someNewValue: 'VALUE1' }, ... ];

Vedi il lodashdocumento di _.forEach https://lodash.com/docs/#forEach

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.