web-dev-qa-db-fra.com

transformer un objet en tableau avec lodash

Comment puis-je transformer un gros object en array avec 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...}]
138
siavolt

Tu peux faire

var arr = _.values(obj);

Pour la documentation voir ici.

227
Daniel Schmidt
_.toArray(obj);

Sorties en tant que:

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

Une solution native moderne pour tous les intéressés:

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

merci pour l'amélioration @KoushikChatterjee

22
Dominic

Pour moi, cela a fonctionné:

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

Ça tourne

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

dans

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

Si vous voulez que la clé (id dans ce cas) soit conservée en tant que propriété de chaque élément du tableau, vous pouvez le faire.

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
11
Sello Mkantjwa

Mise à jour 2017: Object.values , lodash valeurs et toArray faites-le. Et pour conserver les clés map et opérateur spread play Nice:

// 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
Vladimir Chervanev

Transformer un objet en tableau avec du code JavaScript simple (_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);_

Si vous souhaitez également conserver les clés, utilisez Object.entries et Array#map comme ceci:

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

Il y a plusieurs façons d'obtenir le résultat recherché. Permet de les diviser en catégories:

ES6 Valeurs uniquement :

La méthode principale pour cela est Object.values ​​ . Mais en utilisant Object.keys et Array.map vous pourriez aussi bien obtenir le résultat attendu:

_Object.values(obj)
Object.keys(obj).map(k => obj[k])
_
_var obj = {
  A: {
    name: "John"
  },
  B: {
    name: "Ivan"
  }
}

console.log('Object.values:', Object.values(obj))
console.log('Object.keys:', Object.keys(obj).map(k => obj[k]))_

ES6 Key & Value :

Utilisation de la carte et de l’ES6 dynamique/calculé propriétés et déstructurant vous pouvez conserver la clé et renvoyer un objet de la carte.

_Object.keys(obj).map(k => ({[k]: obj[k]}))
Object.entries(obj).map(([k,v]) => ({[k]:v}))
_
_var obj = {
  A: {
    name: "John"
  },
  B: {
    name: "Ivan"
  }
}

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

Valeurs Lodash uniquement :

La méthode conçue à cet effet est _.values mais il existe des "raccourcis" comme _.map et la méthode utilitaire _.toArray qui renverrait également un tableau contenant uniquement les valeurs de l'objet. Vous pouvez également __.map_ si __.keys_ et obtenir les valeurs de l'objet à l'aide de la notation _obj[key]_.

Remarque: __.map_ lorsqu'il est transmis, un objet utilise son gestionnaire baseMap qui est fondamentalement forEach sur les propriétés de l'objet.

__.values(obj)
_.map(obj)
_.toArray(obj)
_.map(_.keys(obj), k => obj[k])
_
_var obj = {
  A: {
    name: "John"
  },
  B: {
    name: "Ivan"
  }
}

console.log('values:', _.values(obj))
console.log('map:', _.map(obj))
console.log('toArray:', _.toArray(obj))
console.log('keys:', _.map(_.keys(obj), k => obj[k]))_
_<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>_

Lodash Key & Value :

_// 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), [])
_
_var obj = {
  A: {
    name: "John"
  },
  B: {
    name: "Ivan"
  }
}

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

// Outputs array with objects containing the keys and values
console.log('entries:', _.map(_.entries(obj), ([k, v]) => ({
  [k]: v
})))
console.log('keys:', _.map(_.keys(obj), k => ({
  [k]: obj[k]
})))
console.log('transform:', _.transform(obj, (r, c, k) => r.Push({
  [k]: c
}), []))
console.log('reduce:', _.reduce(obj, (r, c, k) => (r.Push({
  [k]: c
}), r), []))_
_<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>_

Notez que dans les exemples ci-dessus, ES6 est utilisé (fonctions de flèche et propriétés dynamiques). Vous pouvez utiliser lodash _.fromPairs et d'autres méthodes pour composer un objet si ES6 pose problème.

7
Akrion

var arr = _.map(obj)

Vous pouvez également utiliser la fonction _.map (de lodash et underscore) avec object, elle gérera ce cas en interne, effectuera une itération sur chaque valeur et clé avec votre itéré, et finalement retourner un tableau. Enfait, vous pouvez l'utiliser sans aucune iterere (juste _.map(obj)) si vous voulez juste un tableau de valeurs. La bonne partie est que, si vous avez besoin d'une transformation entre les deux, vous pouvez le faire en une fois.

Exemple:

var obj = {
    key1: {id: 1, name: 'A'},
    key2: {id: 2, name: 'B'},
    key3: {id: 3, name: 'C'}
};

var array1 = _.map(obj, v=>v);
console.log('Array 1: ', array1);

/*Actually you don't need the callback v=>v if you
are not transforming anything in between, v=>v is default*/

//SO simply you can use
var array2 = _.map(obj);
console.log('Array 2: ', array2);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

Toutefois, si vous souhaitez transformer votre objet, vous pouvez le faire, même si vous devez conserver la clé, vous pouvez le faire (_.map(obj, (v, k) => {...}) avec un argument supplémentaire dans map, puis l'utiliser à votre guise.

Cependant, il existe d’autres solutions Vanilla JS à cela (comme chaque solution lodash il devrait y avoir une version JS pure) comme:

  • Object.keys puis map les à valeurs
  • Object.values (en ES-2017)
  • Object.entries puis map chaque paire clé/valeur (dans ES-2017)
  • for...in boucle et utilise chaque touche pour afficher les valeurs

Et beaucoup plus. Mais puisque cette question concerne lodash (et en supposant que quelqu'un l'utilise déjà), vous n'avez pas besoin de beaucoup réfléchir à la version, au support des méthodes et au traitement des erreurs si elles ne sont pas trouvées.

Il existe d'autres solutions lodash telles que _.values (plus lisible à des fins spécifiques), ou l'obtention de paires, puis la mappe, etc. mais dans le cas où votre code a besoin de flexibilité et que vous pouvez le mettre à jour à l'avenir, car vous devez préserver keys ou transformer un peu les valeurs, la meilleure solution consiste à utiliser un seul _.map comme indiqué dans cette réponse. . Cela ne sera pas aussi difficile selon la lisibilité.

5
Koushik Chatterjee

Si vous voulez un mappage personnalisé (comme Array.prototype.map original) d'Object dans un tableau, vous pouvez simplement utiliser _.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' }, ... ];

Voir lodash doc de _.forEach https://lodash.com/docs/#forEach

3
Gil Epshtain