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: [{...}]}

그룹화는 정확하지만 원하는 키 ( color, users) 를 추가하고 싶습니다 . 이것이 가능 _.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?
Benny Bottema 2015

3
lodash 3.10.0 및 모든 단계에 대한 일부 로깅 : jsfiddle.net/plantface/WYCF8/171 . 여전히 퍼즐이지만 나는 거기에 도달하고 있습니다. 하지가 사용한 적이 _.zip_.pair너무 많은 아직.
Benny Bottema 2015

12
lodash 4.x에서는 pairs()메소드가 더 이상 존재하지 않습니다. 이 예제의 업데이트 된 lodash 4.0 버전은 다음과 같습니다..chain(data).groupBy('color') .toPairs().map(function (pair) { return _.zipObject(['Name', 'Suppliers'], air); }).value();
Erik Schierboom

5
나는 loadash가 이것을 매우 정확하게하는 기능을 가져야한다고 느낍니다. 사용자가 항상 속성별로 객체 배열을 그룹화하고 싶어 할 것이라고 생각합니다.
Adam Klein

1
사용 _.chain은 이제 나쁜 습관으로 간주됩니다.
Pawel

89

이렇게 간단하지 않나요?

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

4
이것은 나에게 훨씬 깨끗해 보이며 동일한 결과를 반환하는 것 같습니다. 감사!
Jeremy A. West

3
와. 이것은 어떤 구문입니까? 생성자에 배열을 전달할 수 있다는보고 처음
웨이 JYE

이것은 받아 들여진 대답이어야합니다. 간단하고 깨끗합니다.
Tiago Stapenhorst Martins

17

또 다른 방법

_.chain(data)
    .groupBy('color')
    .map((users, color) => ({ users, color }))
    .value();

@ thefourtheye의 대답과 유사하지만 쉽게 조금 이해하기
마틴 Magakian

당신은 나의 영웅입니다
AlkanV

17

가장 많이 득표 한 답변은 현재 "왜 사용하는 것이 실수인지 " 나쁜 관행으로 간주되는 Lodash _.chain기능을 사용 _.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의 유형 검사는 단순히 구성된 함수로 미쳐 버립니다. pipe()예를 들어 lodash와 같은 RxJS에서 현재와 동일한 수준의 지원이 있기를 바랍니다 .
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.