使用 lodash .groupBy。如何为分组输出添加自己的密钥?

IT技术 javascript sorting underscore.js grouping lodash
2021-01-21 11:43:26

我有这个从 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实用程序?

6个回答

你可以在 Underscore 和 Lodash(3.x 和 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()

使用_.chain现在被认为是一种不好的做法。
2021-03-19 11:43:26
lodash 3.10.0 和每一步的一些日志记录:jsfiddle.net/plantface/WYCF8/171这仍然是一个难题,但我已经到了那里。还没用过_.zip,还_.pair这么多。
2021-03-30 11:43:26
非常漂亮,但很难绕开我的头。你能解释一下中间的步骤吗,尤其是配对和压缩(以及双拉链,因为它_.object是 的别名_.zipObject)。
2021-04-01 11:43:26
在 lodash 4.x 中,该pairs()方法不再存在。此示例的更新 lodash 4.0 版本是:.chain(data).groupBy('color') .toPairs().map(function (pair) { return _.zipObject(['Name', 'Suppliers'], air); }).value();
2021-04-07 11:43:26
我觉得 loadash 应该有一个函数来做这个非常精确的事情。我认为用户总是希望按属性对一组对象进行分组。
2021-04-10 11:43:26

是不是这么简单?

var result = _(data)
            .groupBy(x => x.color)
            .map((value, key) => ({color: key, users: value}))
            .value();
这对我来说似乎更清晰,并且似乎返回了相同的结果。谢谢!
2021-03-27 11:43:26
哇。这是什么语法?第一次看到可以将数组传入构造函数
2021-04-03 11:43:26

投票最高的答案使用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您要转换的数组在哪里

我真的很喜欢你的 map() 语法,非常酷map((users, color) => ({color, users}))而不是map((value, key) => ({ color: key, users: value }))
2021-03-16 11:43:26
我尝试使用flow()而不是chain()这里,但是typescript的类型检查只是对组合函数发疯。我希望我们在 RxJS 中拥有与当前相同级别的支持pipe(),例如,在 lodash 中。
2021-04-06 11:43:26
防止 treeshaking 的问题只适用于 Lodash。在 Underscore 中,您可以自定义_从 1.11 版开始混入的函数
2021-04-12 11:43:26

其他方式

_.chain(data)
    .groupBy('color')
    .map((users, color) => ({ users, color }))
    .value();
类似于@thefourtheye 的答案,但更容易理解
2021-03-18 11:43:26

感谢@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/