nesneyi lodash ile diziye dönüştür


165

Nasıl ben büyük dönüştürebilir objectiçin arraylodash ile?

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 Evet çünkü dokümanlar kütüphaneye çok iyi bir genel bakışa sahipler ... değil. Bu sadece kapsamlı bir işlevler listesidir ve her biri geçerse, zaman kaybı olabilir. Soru adil.
Epirocks

Yanıtlar:


264

Yapabilirsin

var arr = _.values(obj);

Dokümantasyon için buraya bakınız .


34
Anahtarı mülk olarak korumak isterseniz ne olur? (bu örnekte, idmülk mevcut değilse ve her nesnenin anahtarını temel alarak oluşturmak istiyorsanız
Michael Liquori

8
Bunun gibi bir şey yapabilirsiniz:var arr = _.values(_.mapKeys(obj, function(value, key) { value.id = key; return value; }));
Daniel Schmidt

1
@DanielSchmidt Yanlış yaptığımdan emin değilim ama bu örnek benim için sadece 1 satır döndürdü. :( Yani yaptığım şey returndeğeri böyle bir diziye manuel olarak itmek : const divisionsList = []; _.mapKeys(divisions, (value, key) => { divisionsList[key] = value; });Bu yaklaşımı geliştirmek için herhangi bir yorum veya öneri için minnettar olurum
JohnnyQ

8
@JohnnyQ Bunun yerine mapValues ​​kullanmanız gerekeceğini düşünüyorumconst toArrayWithKey = (obj, keyAs) => _.values(_.mapValues(obj, (value, key) => { value[keyAs] = key; return value; }));
orjan

1
@orjan Evet Aslında bunu anladım, güncellemeyi unuttum. Bunun için teşekkür ederim.
JohnnyQ

38
_.toArray(obj);

Çıkışlar:

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

1
_.toArray () İyi çalışıyor @jivings
Syed Zain Ali

4
sadece değerleri almak için iyi bir seçenek, ancak toArraygerekirse anahtarları korumanın bir yolu yok.
Koushik Chatterjee

33

Eğer ilgilenen varsa modern bir yerli çözüm:

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

veya (IE değil):

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

2
neden sadeceObject.keys(obj).map(key=>({key,value: obj[key]}))
Koushik Chatterjee

1
Ben kullanıcı lodash bile değil, aferin efendim!
HungryPipo

1
@Dominic Şimdi tam cevabınızı değiştirdiniz ve herhangi bir söz bile etmeden yorumumdan aldınız (bunu düzenlediniz). Aferin Ko 😁😁
Koushik Chatterjee

1
@KoushikChatterjee tekrar ekledi
Dominic

2
Bu daha yararlı olur mu? const arr = Object.keys(obj).map(id => ({ id, ...obj[id] })); Bu, tüm nesneyi döndürülen verilere getirir mi? (orijinal asker anahtarını kimlik pervane olarak saklamak istediğinden beri 'id' kullanarak)
Zabaat

20

Benim için bu işe yaradı:

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

Döner

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

içine

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

1
Bir nesneyi diziye bir {key: value} -object özgün anahtar nesnenin her anahtar / değer olacak şekilde Array dönüştürmek gerekiyordu. _.toPairs (veri), {"a": "b", "c": "d", "e": "f"} nesnesini alır ve [["a": "gibi bir dizi dizisi olarak döndürür b "], [" c ":" d "], [" e ":" f "]]. _.fromPairs tam tersini yapar, 2 öğeli bir Dizi alır: ["a", "b"] ve bunu nesne olarak döndürür: {"a": "b"}. _.Map kullanarak _.toPairs tarafından oluşturulan diziler _.fromPairs yardımıyla bir nesne dizisine dönüştürülürse dizi üzerinden yinelenir.
NoNine

1
Bunu görmek için aşağı kaydırdığım için mutluyum. Çözümünüz benim için çalıştı! Teşekkürler!
Wale

@NoNine Bir diziye (dizi) harita uygulamanız gerekmez, onu doğrudan giriş nesnesine uygulayabilir ve her anahtar değer çiftini döndürerek _.map(data, (v,k)=>({[k]: v}))ayrıntılar için cevabımı görebilirsiniz. _.toPairsve _fromPairsburada ek ve gereksiz.
Koushik Chatterjee

Sorunun amacı bu değil. çünkü her giriş bir anahtar içerdiğinden (bilmediğiniz gibi) sonucu kullanmak biraz zordur ve yine her bir girişin değerini almak için bazı mantıklardan (örn. Object.keys veya Object.values) geçmeniz gerekir. her biri, oyuncak anahtarları korumak istiyorsa, o zaman gibi yapılandırılmış bir dizi nesne oluşturabilirsiniz[{key: 'someKey', val: 'The value'}, {....},...]
Koushik Chatterjee

13

Sonucunu almak için birkaç yol var. Onları kategorilere ayıralım:

Yalnızca ES6 Değerleri :

Bunun ana yöntemi Object.values . Ancak Object.keys ve Array.map kullanarak beklenen sonuca ulaşabilirsiniz:

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

ES6 Anahtar ve Değer :

Map ve ES6 dinamik / hesaplanmış özellikleri ve yıkımı kullanarak anahtarı tutabilir ve bir nesneyi haritadan döndürebilirsiniz.

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

Yalnızca Lodash Değerleri :

_.valuesAncak bunun için tasarlanan yöntem "kısayollar" gibi _.mapve sadece nesneden değerleri_.toArray içeren bir dizi döndürecek yarar yöntemi vardır . Yapabilirsin da olsa ve kullanarak nesneden değerleri almak gösterimi._.map_.keysobj[key]

Not: _.mapBir nesne iletildiğinde baseMap, temel forEacholarak nesne özellikleri üzerinde bulunan işleyicisini kullanır .

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

Lodash Anahtar ve Değeri :

// 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), [])

Yukarıdaki örneklerde ES6'nın kullanıldığını unutmayın (ok işlevleri ve dinamik özellikler). ES6 _.fromPairsbir sorunsa, nesne oluşturmak için lodash ve diğer yöntemleri kullanabilirsiniz.


12

Anahtarın (bu durumda id) her dizi öğesinin bir özelliği olarak korunmasını istiyorsanız, şunları yapabilirsiniz

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

2017 güncellemesi: Object.values , lodash değerleri ve toArray bunu yapar. Ve tuşları harita korumak ve operatör oyun güzel yaymak için :

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

Nesneyi düz JavaScript'lerle diziye dönüştürme ( 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);

Ayrıca anahtarları kullanmak Object.entriesve Array#mapbu şekilde tutmak istiyorsanız :

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)

_.mapFonksiyonu (her ikisinin lodashve underscore) işlevini de kullanabilirsiniz object, bu durumu dahili olarak işleyecek, her değer ve anahtarı yinelemenizle yineleyecek ve son olarak bir dizi döndürecektir. Infact, _.map(obj)sadece bir değer dizisi istiyorsanız , herhangi bir yineleme olmadan kullanabilirsiniz (sadece ). İyi yanı, arada herhangi bir dönüşüme ihtiyacınız varsa, bunu bir seferde yapabilirsiniz.

Misal:

Ancak, nesnenizi dönüştürmek istiyorsanız, bunu korumanız gerekir, anahtarı korumanız gerekse bile, bunu ( _.map(obj, (v, k) => {...}) ek argüman ile yapabilir mapve daha sonra istediğiniz şekilde kullanabilirsiniz.

Ancak bunun için başka Vanilla JS çözümü var (her lodashçözümün saf JS sürümü olması gerektiği gibi) gibi:

  • Object.keysve sonra maponları değerlere
  • Object.values (ES-2017'de)
  • Object.entriesve sonra mapher bir anahtar / değer çifti (ES-2017'de)
  • for...in döngü ve her tuşa değerleri atmak için kullanın

Ve çok daha fazlası. Ancak bu soru lodash(ve zaten kullanan birini varsayarak) için olduğu için , sürüm, yöntem desteği ve bulunmazsa hata işleme hakkında çok fazla düşünmenize gerek yoktur.

_.values(Belirli bir amaç için daha okunabilir) veya çiftler alıp daha sonra harita vb. Gibi diğer lodash çözümleri vardır . ancak kodunuzun keysdeğerleri biraz korumanız veya dönüştürmeniz gerektiğinde gelecekte güncelleyebileceğiniz esnekliğe ihtiyaç duyması durumunda , en iyi çözüm _.mapbu cevabı addresed olarak bir tekli kullanmaktır . Bu okunabilirliğe göre o kadar da zor olmayacak.


2
Güzel, çok basit ve en özlü.
edencorbin

5

Diziye Nesne

Tüm cevaplar arasında bunun en iyisi olduğunu düşünüyorum:

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

dönüştüren:

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

için:

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

Nesne Dizisi

Geri dönüşümü yapmak için:

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

Anahtarı değerde tutarak geri dönüştürmek için:

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

Verecek:

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

Son örnek için ayrıca lodash _.keyBy(arr, 'key')veya kullanabilirsiniz _.keyBy(arr, i => i.key).


3

Object'in bir Array ile bazı özel eşlemesini (orijinal Array.prototype.map gibi) istiyorsanız, şunu kullanabilirsiniz _.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' }, ... ];

lodash_.ForEach belgesine bakın https://lodash.com/docs/#forEach

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.