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

use*_*105 85 javascript sorting grouping underscore.js lodash

我有一个从API返回的示例数据.

我正在使用Lodash _.groupBy将数据转换为我可以更好地使用的对象.返回的原始数据是:

[
    {
        "name": "jim",
        "color": "blue",
        "age": "22"
    },
    {
        "name": "Sam",
        "color": "blue",
        "age": "33"
    },
    {
        "name": "eddie",
        "color": "green",
        "age": "77"
    }
]
Run Code Online (Sandbox Code Playgroud)

我希望_.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"
            }
        ]
    }
]
Run Code Online (Sandbox Code Playgroud)

目前我正在使用

_.groupBy(a, function(b) { return b.color})
Run Code Online (Sandbox Code Playgroud)

这是归还这个.

{blue: [{..}], green: [{...}]}
Run Code Online (Sandbox Code Playgroud)

分组是正确的,但我真的想添加我想要的键(color,users).这有可能用_.groupBy吗?或其他一些LoDash实用工具?

the*_*eye 112

你可以这样做

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()
);
Run Code Online (Sandbox Code Playgroud)

在线演示

注意: Lodash 4.0以后,该.pairs功能已重命名为_.toPairs()

  • 在lodash 4.x中,`pairs()`方法不再存在.此示例的更新lodash 4.0版本是:`.chain(data).groupBy('color').toPairs().map(function(pair){return _.zipObject(['Name','Suppliers'], air);}).value();` (12认同)
  • 我觉得loadash应该有一个完成这个非常精确的功能.我认为用户会希望一直按属性对一组对象进行分组. (4认同)
  • lodash 3.10.0以及每一步的一些记录:http://jsfiddle.net/plantface/WYCF8/171/.它仍然是一个难题,但我到了那里.还没有使用过`_.zip`和`_.pair`这么多. (2认同)

Dar*_*agh 76

这不简单吗?

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

  • 哇。这是什么语法?第一次看到可以将数组传入构造函数 (5认同)
  • 对我来说,这似乎更干净,并且似乎返回了相同的结果。谢谢! (3认同)

sta*_*las 15

其他方式

_.chain(data)
    .groupBy('color')
    .map((users, color) => ({ users, color }))
    .value();
Run Code Online (Sandbox Code Playgroud)


Paw*_*wel 13

最高投票回答使用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)
Run Code Online (Sandbox Code Playgroud)

input您要转换的数组在哪里.


Mat*_*att 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;
        }
Run Code Online (Sandbox Code Playgroud)

要使用它:

var result = groupBy(data, 'color', 'colorId', 'users');
Run Code Online (Sandbox Code Playgroud)

这是更新的提琴手;

https://jsfiddle.net/sc2L9dby/


Ngu*_*ong 6

使用其他答案看起来不错lodash

我建议使用 JavaScript 的不同方法,例如Array#reduceobject for storing??=语法。因此,它只需要O(n)时间复杂度。

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

const result = data.reduce((acc, {
  name,
  color,
  age
}) => {
  acc[color] ??= {
    color: color,
    users: []
  };
  acc[color].users.push({
    name,
    color,
    age
  });

  return acc;
}, {});
console.log(Object.values(result));
Run Code Online (Sandbox Code Playgroud)


mat*_*hew 5

这是使用lodash 4和ES6的更新版本

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