オブジェクトをlodashで配列に変換する


165

ロダッシュでビッグobjectをどのように変換できarrayますか?

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はい、ドキュメントにはライブラリの非常に優れた概要があるので...そうではありません。これは関数の完全なリストにすぎません。各関数を調べてみると、関数がない場合は時間の浪費になる可能性があります。問題は公平なものです。
Epirocks

回答:


263

できるよ

var arr = _.values(obj);

ドキュメントについては、こちらをご覧ください。


34
キーをプロパティとして保持したい場合はどうでしょうか?(この例では、場合idプロパティが存在していなかった、あなたは、各オブジェクトのキーに基づいて、それを作成したい。
マイケルLiquori

8
:あなたはこのような何かを行うことができますvar arr = _.values(_.mapKeys(obj, function(value, key) { value.id = key; return value; }));
ダニエル・シュミット

1
@DanielSchmidt何を間違えたかわかりませんが、そのサンプルでは1行しか返されませんでした。:(だから何私がやったことは、手動でプッシュしているreturn。このような配列に値を:const divisionsList = []; _.mapKeys(divisions, (value, key) => { divisionsList[key] = value; });私はこのアプローチを改善するために、任意のコメントや提案をいただければと思います。
JohnnyQ

8
@JohnnyQ代わりにmapValuesを使用する必要があると思います。例const toArrayWithKey = (obj, keyAs) => _.values(_.mapValues(obj, (value, key) => { value[keyAs] = key; return value; }));
orjan

1
@orjanはい私は実際にこれを理解しました、更新するのを忘れました。有難うございます。
JohnnyQ 2016年

38
_.toArray(obj);

出力:

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

1
_.toArray()は@jivingsで問題なく動作します
Syed Zain Ali

4
値のみを取得するための適切なオプションですが、toArray必要に応じてキーを保持する方法はありません。
Koushik Chatterjee

33

興味のある方のための最新のネイティブソリューション:

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

または(IE以外):

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

2
なぜだけではないのかObject.keys(obj).map(key=>({key,value: obj[key]}))
コシクチャタジー

1
私はそれがユーザーlodashでさえないのが好きです。
HungryPipo

1
@Dominic今、あなたはあなたの完全な答えを変更し、言及がなくても私のコメントからそれを取りました(あなたはそれを編集しました)。よくやった👏😁😁
コウシクチャタジー

1
@KoushikChatterjeeが追加し直しました
ドミニク

2
これはもっと役に立ちますか? const arr = Object.keys(obj).map(id => ({ id, ...obj[id] })); これはオブジェクト全体を返されたデータに持ち込むでしょうか?(元の
質問者が

20

私にとって、これはうまくいきました:

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

回る

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

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

1
元のオブジェクトの各キー/値が配列内の{key:value}オブジェクトになるように、オブジェクトを配列に変換する必要がありました。_.toPairs(data)はオブジェクト{"a": "b"、 "c": "d"、 "e": "f"}を受け取り、[["a": "のような配列の配列として返しますb "]、[" c ":" d "]、[" e ":" f "]]。_.fromPairsはその逆を行い、2つの要素を持つ配列[[a "、" b "]を受け取り、それをオブジェクトとして返します:{" a ":" b "}。_.mapの使用_.toPairsによって作成された配列が_.fromPairsを使用してオブジェクトの配列に変換する場合は、配列を反復処理しました。
NoNine 2017

1
これを見るためにスクロールダウンしてよかったです。あなたの解決策は私のために働いた!ありがとう!
ウェール

@NoNine(配列の)配列にマップを適用する必要はありません。入力オブジェクトに直接適用して、各キーと値のペア_.map(data, (v,k)=>({[k]: v}))を返すことができます。詳細については、私の回答を参照してください。_.toPairsそして_fromPairs、ここで追加し、不要です。
Koushik Chatterjee

これは質問の対象ではありません。各エントリにキー(わからない)が含まれているため、結果を使用するのは少し難しいため、値を取得するには、エントリごとにいくつかのロジック(Object.keysやObject.valuesなど)を実行する必要があります。それぞれ、おもちゃがキーを保持したい場合は、次のように構造化されたオブジェクトの配列を作成できます[{key: 'someKey', val: 'The value'}, {....},...]
Koushik Chatterjee

13

あなたが望んでいる結果を得るにはかなり多くの方法があります。それらをカテゴリーに分けましょう:

ES6値のみ

このための主なメソッドはObject.valuesです。ただし、Object.keysArray.mapを使用すると、期待どおりの結果が得られます。

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

ES6のキーと値

マップおよびES6を使用して、動的/計算されたプロパティをし、構造化代入あなたが鍵を保持し、マップからオブジェクトを返すことができます。

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

Lodash値のみ

このために設計されたメソッド_.valuesは、「ショートカット」のようなもので_.mapあり、オブジェクトからの値のみ_.toArrayを含む配列も返すユーティリティメソッドがあります。あなたは可能性もかかわらず、そして使用して、オブジェクトから値を取得する表記を。_.map_.keysobj[key]

注:_.map渡されたオブジェクトbaseMapは、基本的forEachにオブジェクトのプロパティにあるハンドラーを使用します。

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

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

上記の例ではES6が使用されていることに注意してください(矢印関数と動的プロパティ)。_.fromPairsES6に問題がある場合は、lodash およびその他のメソッドを使用してオブジェクトを作成できます。


12

キー(この場合はid)を各配列項目のプロパティとして保存したい場合は、

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年の更新:Object.values、lodash 、およびtoArrayがそれを行います。また、キーマップを保存し、オペレーターをうまく再生するには、次のようにします。

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

プレーンなJavaScriptECMAScript-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);

キーの使用も維持したい場合はObject.entries、次のArray#mapようにします。

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)

あなたが使用することができます_.map(両方の機能lodashunderscoreとの)objectだけでなく、それは内部的に反復は、あなたのiterateeと各値とキーの上に、そのケースを処理し、最終的には配列を返します。実際、_.map(obj)値の配列だけが必要な場合は、繰り返しなしで(ちょうど)使用できます。良い点は、間に変換が必要な場合は、一度に実行できることです。

例:

ただし、オブジェクトを変換したい場合は、キーを保持する必要がある場合でも、それを行うことができます。_.map(obj, (v, k) => {...}追加の引数を指定しmapてそれを()実行し、必要に応じて使用できます。

ただし、これには他のVanilla JSソリューションがあります(すべてのlodashソリューションには純粋なJSバージョンが必要です)。

  • Object.keysそしてmapそれらを値に
  • Object.values (ES-2017で)
  • Object.entriesそして、map各キー/値ペア(ES-2017)
  • for...in ループし、値を取得するために各キーを使用します

そしてもっとたくさん。しかし、この質問はlodash(そして誰かがすでにそれを使用していると仮定して)ためのものなので、バージョン、メソッドのサポート、およびそれらが見つからない場合のエラー処理について多くを考える必要はありません。

他のlodashソリューション_.values(特定の目的でより読みやすい)、またはペアを取得してからマップするなどがあります。ただし、コードに柔軟性を必要とする場合は、keys値を少し保持または変換する必要があるため、将来的にコードを更新できるため、最適な解決策は_.map、この回答で追加されたシングルを使用することです。それは読みやすさによってもそれほど難しくありません。


2
素敵で、とてもシンプルで、最も簡潔です。
エデンコルビン2017年

5

配列するオブジェクト

すべての答えのうち、私はこれが最良だと思います:

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

それは変換します:

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

に:

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

オブジェクトへの配列

元に戻すには:

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

キーを値に保持して変換を戻すには:

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

あげる:

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

最後の例では、lodash _.keyBy(arr, 'key')またはを使用することもできます_.keyBy(arr, i => i.key)


3

オブジェクトの配列へのカスタムマッピング(元のArray.prototype.mapなど)が必要な場合は、次のように使用できます_.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 https://lodash.com/docs/#forEachのドキュメントを参照してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.