【问题标题】:lodash Groupby based on multiple conditionslodash Groupby 基于多个条件
【发布时间】:2018-02-02 07:31:41
【问题描述】:

我在我的一个项目中使用 angular 4,我遇到了一种情况,我必须根据多个条件对数据进行分组,如下所述。

原始数据

[
{
    age: "12",
    details: [
        {
            address: "street1"
        }
    ]
},
{
    age: "12",
    details: [
        {
            address: "street2"
        }
    ]
},
{
    age: "12",
    details: [
        {
            address: "street1"
        }
    ]
}]

我想根据年龄和地址字段对数据进行分组,所以结果会是这样的

{
 stree1: [{
        age: "12",
        details: [
            {
                address: "street1"
            }
        ]
    }, {
        age: "12",
        details: [
            {
                address: "street1"
            }
        ]
    }

    ],
        street2: [{
            age: "12",
            details: [
                {
                    address: "street1"
                }
            ]
        }]
    }

我知道我们可以使用 lodash 根据单个条件对数据进行分组,例如

_.groupBy(data, 'age');

但我不明白如何根据多种条件执行此操作。我想将所有具有相同地址和相同年龄的对象分组。类似的东西

_.groupBy(data, 'age' && details[0].address);

如何解决这个问题。请帮忙。

【问题讨论】:

  • 如果他们中的一些人已经 14 岁了,怎么办?你能给出预期的输出吗?
  • 我明白你为什么问这个问题.. 有没有办法只输出那些匹配的对象并丢弃那些没有匹配的对象。即在给定的示例中,street2 数据甚至不会存在...
  • 所以如果有多个对象的组合值为街道+地址,那么只有它会出现分组?是吗?
  • 另外,detaills 数组将只有一个对象?或者其他条目可以在那里?
  • 是的,细节永远只有一个对象

标签: javascript angular lodash angular2-services


【解决方案1】:

如果您确定您的对象结构始终完全相同并且在details 中只有一个对象,那么您可以直接进行Stringify 来识别组合,如果您的对象有多个数据,那么您可以创建一个新对象{age: value, street: value} 并将其字符串化以识别组合。但是,我强烈建议不要使用任何管道或任何东西作为分隔符,并加入它们以创建唯一的字符串组合以查找组。有时这会破坏你的价值。

这是你需要的:

_(rawData).groupBy(JSON.stringify).filter(arr=>arr.length>1).mapKeys(v=>v[0].details[0].address).value()

这是一个工作示例:

var rawData = [
{
    age: "12",
    details: [
        {
            address: "street1"
        }
    ]
},
{
    age: "12",
    details: [
        {
            address: "street2"
        }
    ]
},
{
    age: "12",
    details: [
        {
            address: "street1"
        }
    ]
}];

var result = _(rawData)
                .groupBy(JSON.stringify)
                .filter(arr=>arr.length>1)
                .mapKeys(v=>v[0].details[0].address)
                .value();
                
console.log('Expected result: ', result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

如果你的对象中可能有多个其他东西,你会这样做

var rawData = [
{
    age: "12",
    details: [
        {
            address: "street1"
        }
    ]
},
{
    age: "12",
    details: [
        {
            address: "street2"
        }
    ]
},
{
    age: "12",
    details: [
        {
            address: "street1"
        }
    ]
}];

var result = _(rawData)
                .groupBy(obj=>JSON.stringify({age: obj.age, address: obj.details[0].address}))
                .filter(arr=>arr.length>1)
                .mapKeys(v=>v[0].details[0].address)
                .value();
                
console.log('Expected result: ', result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

【讨论】:

  • 但是即使给出了这个答案,我仍然有一个问题。您想要那些出现地址和年龄组合的数据,但是您只想将 addrss 作为键,现在假设有 2 个带有 address: street1, age 10 的对象和 3 个带有 address: street2, age 30 的对象,那么键对于两个组对吗??所以基本上不可能,最终你会丢失你的数据,因为下一个键将覆盖!!
  • 是的,在我的情况下这很好,因为数据将根据优先级进行排序
【解决方案2】:

类似:

const res = _.chain(arr)
    .groupBy('age')
    .mapValues(ageArr => _.groupBy(ageArr, ageObj => ageObj.details[0].address))
    .value();

【讨论】:

    猜你喜欢
    • 2021-10-19
    • 1970-01-01
    • 2019-04-10
    • 2020-10-10
    • 1970-01-01
    • 1970-01-01
    • 2017-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多