lodash .groupByを使用します。グループ化された出力に独自のキーを追加するにはどうすればよいですか?


104

このサンプルデータはAPIから返されます。

Lodash _.groupByを使用して、データをより使いやすいオブジェクトに変換しています。返される生データはこれです:

[
    {
        "name": "jim",
        "color": "blue",
        "age": "22"
    },
    {
        "name": "Sam",
        "color": "blue",
        "age": "33"
    },
    {
        "name": "eddie",
        "color": "green",
        "age": "77"
    }
]

この_.groupBy関数が次のようなオブジェクトを返すようにしたい:

[
    {
        color: "blue",
        users: [
            {
                "name": "jim",
                "color": "blue",
                "age": "22"
            },
            {
                "name": "Sam",
                "color": "blue",
                "age": "33"
            }
        ]
    },
    {
        color: "green",
        users: [
            {
                "name": "eddie",
                "color": "green",
                "age": "77"
            }
        ]
    }
]

現在使用しています

_.groupBy(a, function(b) { return b.color})

これを返しています。

{blue: [{..}], green: [{...}]}

グループ化は正しいですが、必要なキー(colorusers)を追加したいと思います。これは可能_.groupByですか?または他のLoDashユーティリティ?

回答:


140

あなたはLodash 4.xでこのようにそれを行うことができます

var data = [{
  "name": "jim",
  "color": "blue",
  "age": "22"
}, {
  "name": "Sam",
  "color": "blue",
  "age": "33"
}, {
  "name": "eddie",
  "color": "green",
  "age": "77"
}];

console.log(
  _.chain(data)
    // Group the elements of Array based on `color` property
    .groupBy("color")
    // `key` is group's name (color), `value` is the array of objects
    .map((value, key) => ({ color: key, users: value }))
    .value()
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>


元の回答

var result = _.chain(data)
    .groupBy("color")
    .pairs()
    .map(function(currentItem) {
        return _.object(_.zip(["color", "users"], currentItem));
    })
    .value();
console.log(result);

オンラインデモ

注: Lodash 4.0以降、.pairs関数の名前は_.toPairs()


非常に気の利いた、しかし私の頭を包むのは難しい。(以降、およびダブルジップあなたは、特にペアリングとビュンとの間での手順を説明することができます_.objectの別名です_.zipObject)。
ベニーボッテマ2015

3
lodash 3.10.0およびすべてのステップのいくつかのロギング:jsfiddle.net/plantface/WYCF8/171。それはまだパズルですが、私はそこに着いています。使用していない_.zip_.pair、まだそんなに。
ベニーボッテマ2015

12
lodash 4.xでは、このpairs()メソッドはもう存在しません。この例のlodash更新4.0バージョンがある:.chain(data).groupBy('color') .toPairs().map(function (pair) { return _.zipObject(['Name', 'Suppliers'], air); }).value();
エリックSchierboom

5
loadashには、この非常に正確なことを行う関数が必要だと思います。ユーザーは常にオブジェクトの配列をプロパティごとにグループ化したいと思うでしょう。
アダムクライン

1
使用すること_.chainは今では悪い習慣と考えられています。
Pawel

88

こんなに簡単ではないですか?

var result = _(data)
            .groupBy(x => x.color)
            .map((value, key) => ({color: key, users: value}))
            .value();

4
これは私にはかなりすっきりしていて、同じ結果を返しているようです。ありがとう!
ジェレミーA.ウェスト

3
ワオ。これはどの構文ですか?配列をコンストラクタに渡すことができるのは初めてです
Wei-jye 2018

これは受け入れられる答えになるはずです。シンプルでクリーン。
Tiago Stapenhorst Martins


17

最高得点の_.chain 回答は、現在不適切使用であるという悪い習慣と見なされているLodash 関数を使用してます_.chain

以下は、関数型プログラミングの観点から問題に取り組むいくつかのライナーです。

import tap from "lodash/fp/tap";
import flow from "lodash/fp/flow";
import groupBy from "lodash/fp/groupBy";

const map = require('lodash/fp/map').convert({ 'cap': false });

const result = flow(
      groupBy('color'),
      map((users, color) => ({color, users})),
      tap(console.log)
    )(input)

input変換したい配列はどこですか?


flow()chain()ここの代わりに使用しようとしましたが、typescriptの型チェックは、構成された関数に夢中になるだけです。ロダッシュなど、RxJSで現在サポートしているのと同じレベルのサポートがあることを願っていpipe()ます。
BrunoJCM

私はあなたのmap()構文が本当に好きです。map((users, color) => ({color, users}))代わりにとてもクールですmap((value, key) => ({ color: key, users: value }))
Gil Epshtain

7

@thefourtheyeに感謝します。コードは大いに役立ちました。Lodashのバージョン4.5.0を使用して、ソリューションから汎用関数を作成しました。

function groupBy(dataToGroupOn, fieldNameToGroupOn, fieldNameForGroupName, fieldNameForChildren) {
            var result = _.chain(dataToGroupOn)
             .groupBy(fieldNameToGroupOn)
             .toPairs()
             .map(function (currentItem) {
                 return _.zipObject([fieldNameForGroupName, fieldNameForChildren], currentItem);
             })
             .value();
            return result;
        }

それを使用するには:

var result = groupBy(data, 'color', 'colorId', 'users');

これが更新されたフィドラーです。

https://jsfiddle.net/sc2L9dby/


5

lodash 4とES6を使用した更新バージョンは次のとおりです

const result = _.chain(data)
    .groupBy("color")
    .toPairs()
    .map(pair => _.zipObject(['color', 'users'], pair))
    .value();

2

私は別のアプローチを提案します。自分のライブラリを使用するとこれを数行で実行できます。

var groupMe = sequence(
  groupBy(pluck('color')),
  forOwn(function(acc, k, v) {
    acc.push({colors: k, users: v});
    return acc;
  },[])
);

var result = groupMe(collection);

引数が逆順であるため、lodashまたはUnderscoreではこれは少し難しいため、_.partialたくさん使用する必要があります。


2

Lodash 4.17.4を使用したgroupByおよび列の合計の例

   var data = [{
                "name": "jim",
                "color": "blue",
                "amount": 22
                }, {
                "name": "Sam",
                "color": "blue",
                "amount": 33
                }, {
               "name": "eddie",
               "color": "green",
               "amount": 77
              }];

      var result = _(data)
                   .groupBy(x => x.color)
                   .map((value, key) => 
                   ({color: key,
                    totalamount: _.sumBy(value,'amount'),
                    users: value})).value();

                    console.log(result);

いい...そして最新
Peter van der Lely

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