mengubah objek menjadi array dengan lodash

165

Bagaimana saya bisa mengubah besar objectmenjadi arraydengan 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...}]
siavolt
sumber
@Munjunjay Ya karena dokumen memiliki tinjauan perpustakaan yang hebat ... tidak. Ini hanya daftar lengkap fungsi dan melalui masing-masing bisa membuktikan buang-buang waktu jika tidak ada. Pertanyaannya adalah pertanyaan yang adil.
Epirocks

Jawaban:

263

Anda dapat melakukan

var arr = _.values(obj);

Untuk dokumentasi lihat di sini.

Daniel Schmidt
sumber
34
Bagaimana jika Anda ingin mempertahankan kunci sebagai properti? (dalam contoh ini, jika idproperti itu tidak ada dan Anda ingin membuatnya berdasarkan kunci dari masing-masing objek.
Michael Liquori
8
Anda dapat melakukan sesuatu seperti ini:var arr = _.values(_.mapKeys(obj, function(value, key) { value.id = key; return value; }));
Daniel Schmidt
1
@DanielSchmidt Saya tidak yakin apa yang saya lakukan salah tetapi sampel itu hanya mengembalikan 1 baris untuk saya. :( Jadi yang saya lakukan adalah secara manual mendorong returnnilai ke array seperti ini: const divisionsList = []; _.mapKeys(divisions, (value, key) => { divisionsList[key] = value; });Saya menghargai komentar atau saran untuk meningkatkan pendekatan ini.
JohnnyQ
8
@ JohnnyQ Saya pikir Anda harus menggunakan mapValues ​​sebagai gantinyaconst toArrayWithKey = (obj, keyAs) => _.values(_.mapValues(obj, (value, key) => { value[keyAs] = key; return value; }));
orjan
1
@orjan Ya saya benar-benar menemukan ini, hanya lupa untuk memperbarui. Terima kasih untuk itu.
JohnnyQ
38
_.toArray(obj);

Output sebagai:

[
  {
    "name": "Ivan",
    "id": 12,
    "friends": [
      2,
      44,
      12
    ],
    "works": {
      "books": [],
      "films": []
    }
  },
  {
    "name": "John",
    "id": 22,
    "friends": [
      5,
      31,
      55
    ],
    "works": {
      "books": [],
      "films": []
    }
  }
]"
Jivings
sumber
1
_.toArray () Bekerja dengan baik pada @ jivings
Syed Zain Ali
4
untuk mendapatkan hanya nilai-nilai itu merupakan opsi yang baik, tetapi toArraytidak ada cara untuk mempertahankan kunci jika diperlukan.
Koushik Chatterjee
33

Solusi asli modern jika ada yang tertarik:

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

atau (bukan IE):

const arr = Object.entries(obj).map(([key, value]) => ({ key, value }));
Dominic
sumber
2
mengapa tidak sajaObject.keys(obj).map(key=>({key,value: obj[key]}))
Koushik Chatterjee
1
Saya suka itu bahkan tidak pengguna lodash, dilakukan dengan baik pak!
HungryPipo
1
@Dominic Sekarang Anda mengubah jawaban lengkap Anda dan mengambilnya dari komentar saya, bahkan tanpa menyebutkan (Anda mengeditnya). Bagus sekali 👏 😁😁
Koushik Chatterjee
1
@KoushikChatterjee menambahkannya kembali
Dominic
2
Apakah ini akan lebih membantu? const arr = Object.keys(obj).map(id => ({ id, ...obj[id] })); ini akan membawa seluruh objek ke dalam data yang dikembalikan no? (menggunakan 'id' karena penanya asli ingin menyimpan kuncinya sebagai prop id)
zabaat
20

Bagi saya, ini berhasil:

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

Itu berputar

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

ke

[{"a":"b"}, {"c":"d"}, {"e":"f"}]
NoNine
sumber
1
Saya perlu mengubah objek menjadi Array, dengan cara bahwa setiap kunci / nilai objek asli akan menjadi {key: value} -object dalam array. _.toPairs (data) mengambil objek {"a": "b", "c": "d", "e": "f"} dan mengembalikannya sebagai array array seperti [["a": " b "], [" c ":" d "], [" e ":" f "]]. _.fromPairs melakukan yang sebaliknya, dibutuhkan Array dengan 2 elemen: ["a", "b"] dan mengembalikannya sebagai objek: {"a": "b"}. Menggunakan _.map saya mengulangi array jika array yang dibuat oleh _.toPairs untuk mengubahnya menjadi array objek dengan bantuan _.fromPairs.
NoNine
1
Saya senang saya menggulir ke bawah untuk melihat ini. Solusi Anda berhasil untuk saya! Terima kasih!
Wale
@NoNine Anda tidak perlu menerapkan peta pada array (array), Anda dapat langsung menerapkannya pada objek input, dan mengembalikan setiap pasangan nilai kunci untuk _.map(data, (v,k)=>({[k]: v}))melihat jawaban saya untuk detail. _.toPairsdan _fromPairstambahan dan tidak perlu di sini.
Koushik Chatterjee
Bukan itu maksud pertanyaan itu. karena agak sulit untuk menggunakan hasilnya karena setiap entri berisi kunci (yang Anda tidak tahu) dan sekali lagi Anda harus melalui beberapa logika (misalnya Object.keys atau Object.values) untuk setiap entri terpisah untuk mendapatkan nilai masing-masing, jika mainan ingin mempertahankan kunci maka Anda dapat membuat berbagai objek yang disusun seperti[{key: 'someKey', val: 'The value'}, {....},...]
Koushik Chatterjee
13

Ada beberapa cara untuk mendapatkan hasil yang Anda kejar. Mari kita pecahkan dalam kategori:

Nilai ES6 saja :

Metode utama untuk ini adalah Object.values . Tetapi menggunakan Object.keys dan Array.map Anda juga bisa mendapatkan hasil yang diharapkan:

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

Nilai & Nilai ES6 :

Menggunakan peta dan ES6 dinamis / sifat-sifat yang dikomputasi dan perusakan Anda dapat mempertahankan kunci dan mengembalikan objek dari peta.

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

Hanya Nilai Lodash :

Metode yang dirancang untuk ini adalah _.valuesada "pintas" seperti _.mapdan metode utilitas _.toArrayyang juga akan mengembalikan array yang hanya berisi nilai-nilai dari objek. Anda juga bisa _.mapmelihat _.keysdan mendapatkan nilai dari objek dengan menggunakan obj[key]notasi.

Catatan: _.mapketika melewati sebuah objek akan menggunakan baseMaphandlernya yang pada dasarnya forEachberada di properti objek.

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

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

Perhatikan bahwa dalam contoh di atas ES6 digunakan (fungsi panah dan properti dinamis). Anda bisa menggunakan lodash _.fromPairsdan metode lain untuk membuat objek jika ES6 merupakan masalah.

Akrion
sumber
12

Jika Anda ingin kunci (id dalam hal ini) dipertahankan sebagai properti dari setiap item array yang dapat Anda lakukan

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
Sello Mkantjwa
sumber
8

Pembaruan 2017: Object.values , nilai lodash, dan toArray melakukannya. Dan untuk melestarikan kunci peta dan menyebar operator bermain bagus:

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

Vladimir Chervanev
sumber
7

Mengubah objek menjadi array dengan JavaScript biasa ( 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);

Jika Anda juga ingin tetap menggunakan tombol Object.entriesdan Array#mapsuka ini:

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

BlackBeard
sumber
5

var arr = _.map(obj)

Anda dapat menggunakan _.mapfungsi (keduanya lodashdan underscore) dengan objectjuga, itu akan menangani kasus itu secara internal, beralih ke setiap nilai dan kunci dengan iterate Anda, dan akhirnya mengembalikan array. Infact, Anda dapat menggunakannya tanpa iteratee (adil)_.map(obj) ) jika Anda hanya menginginkan array nilai. Bagian baiknya adalah bahwa, jika Anda memerlukan transformasi apa pun di antaranya, Anda dapat melakukannya dalam sekali jalan.

Contoh:

Namun, jika Anda ingin mengubah objek Anda dapat melakukannya, bahkan jika Anda perlu mempertahankan kunci, Anda dapat melakukannya ( _.map(obj, (v, k) => {...}) dengan argumen tambahan di mapdan kemudian menggunakannya seperti yang Anda inginkan.

Namun ada solusi Vanilla JS lainnya untuk ini (karena setiap lodashsolusi harus ada versi JS murni itu) seperti:

  • Object.keysdan kemudian mapmereka untuk nilai
  • Object.values (dalam ES-2017)
  • Object.entries lalu map setiap pasangan kunci / nilai (dalam ES-2017)
  • for...in lingkaran dan gunakan setiap tombol untuk nilai feting

Dan masih banyak lagi. Tapi karena pertanyaan ini untuklodash (dan mengasumsikan seseorang sudah menggunakannya) maka Anda tidak perlu berpikir banyak tentang versi, mendukung metode dan penanganan kesalahan jika tidak ditemukan.

Ada solusi lodash lain seperti _.values(lebih mudah dibaca untuk perpose tertentu), atau mendapatkan pasangan dan kemudian memetakan dan sebagainya. tetapi dalam hal kode Anda memerlukan fleksibilitas agar Anda dapat memperbaruinya di masa depan karena Anda perlu sedikit melestarikan keysatau mengubah nilai, maka solusi terbaik adalah menggunakan satu _.mapseperti ditambahkan dalam jawaban ini. Itu tidak akan terlalu sulit karena mudah dibaca juga.

Koushik Chatterjee
sumber
2
Bagus, sangat sederhana dan paling ringkas.
edencorbin
5

Objek untuk Array

Dari semua jawaban saya pikir yang ini adalah yang terbaik:

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

yang mengubah:

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

untuk:

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

Array ke Objek

Untuk mengubah kembali:

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

Untuk mengubah kembali menjaga kunci dalam nilai:

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

Akan memberi:

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

Untuk contoh terakhir Anda juga dapat menggunakan lodash _.keyBy(arr, 'key')atau _.keyBy(arr, i => i.key).

orad
sumber
3

Jika Anda ingin pemetaan khusus (seperti Array.prototype.map) asli dari Obyek menjadi Array, Anda bisa menggunakan _.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' }, ... ];

Lihat lodashdokumen _.forEach https://lodash.com/docs/#forEach

Gil Epshtain
sumber