【问题标题】:Sorting after grouping objects in Javascript在Javascript中对对象进行分组后排序
【发布时间】:2020-04-02 08:37:13
【问题描述】:

假设我有以下数据:

const collection = [
        {
            callId: "1",
            deadline: null
        },
        {
            callId: "1",
            deadline: null
        },
        {
            callId: "3",
            deadline: "2020-04-02T13:37:00.000Z" //assume its a JS date object
        },
        {
            callId: "3",
            deadline: "2020-04-06T08:33:00.000Z" //assume its a JS date object
        },
        {
            callId: "2",
            deadline: null
        },
        {
            callId: "2",
            deadline: "2020-04-06T08:33:00.000Z" //assume its a JS date object
        },
    ]

我想按callId 对它们进行分组,但分组数据按deadline 排序。所以我想要的结果是:

const sorted = {
        "3": [
            {
                callId: "3",
                deadline: "2020-04-02T13:37:00.000Z"
            },
            {
                callId: "3",
                deadline: "2020-04-06T08:33:00.000Z"
            },
        ],
        "2": [
            {
                callId: "2",
                deadline: "2020-04-06T08:33:00.000Z"
            },
            {
                callId: "2",
                deadline: null
            },
        ],
        "1": [
            {
                callId: "1",
                deadline: null
            },
            {
                callId: "1",
                deadline: null
            },
        ],
    }

我尝试使用lodash

const groupedData = _groupBy(collection, 'callId')
const sortedData = _sortBy(groupedData, [function (resultItem) {
        return _map(resultItem, function (value) {
            return value.deadline == null;
        });
    }]);

但我没有设法得到正确的结果:

[
[
    {
        "callId": "3",
        "deadline": "2020-04-02T13:37:00.000Z"
    },
    {
        "callId": "3",
        "deadline": "2020-04-06T08:33:00.000Z"
    }
],
[
    {
        "callId": "2",
        "deadline": null
    },
    {
        "callId": "2",
        "deadline": "2020-04-06T08:33:00.000Z"
    }
],
[
    {
        "callId": "1",
        "deadline": null
    },
    {
        "callId": "1",
        "deadline": null
    }
]
]

【问题讨论】:

  • 你想得到sorted吗?作为对象?
  • 按最近的日期排序并按 callId 分组
  • 您不能通过具有索引的键对对象进行排序。

标签: javascript object lodash


【解决方案1】:

首先根据日期对数组进行排序,然后使用 JavaScript 内置的Array Reduce 方法

let collection = [
        {
            callId: "1",
            deadline: null
        },
        {
            callId: "1",
            deadline: null
        },
        {
            callId: "3",
            deadline: "2020-04-02T13:37:00.000Z"
        },
        {
            callId: "3",
            deadline: "2020-04-06T08:33:00.000Z"
        },
        {
            callId: "2",
            deadline: null
        },
        {
            callId: "2",
            deadline: "2020-04-06T08:33:00.000Z"
        },
    ]

 // Sort based on date (Null values will be placed at the last)
 collection = collection.sort((a,b) => {
   if (a.deadline === null) {
     return 1;
   }
   else if (b.deadline === null) {
     return -1;
   } else {
     return new Date(a.deadline) - new Date(b.deadline)
   }
})
    
 // convert the array to object using reduce method
 const grouped = collection.reduce((a,c) => ({
   ...a,
   // Check if the key already exist,
   // if yes, append the item to the array
   // or create a new array 
   [c.callId]: a[c.callId] ? [...a[c.callId], c] : [c] 
  }), {})
 
 console.log(grouped)

JavaScript 中对象键的顺序

JavaScript 中对象的属性没有顺序。在某些浏览器中似乎有一个顺序,但 ECMAScript 规范将对象属性枚举顺序定义为特定于实现的,因此您不应假设一个浏览器的行为与另一个浏览器的行为相同。

如果顺序对您很重要,请使用数组。

【讨论】:

  • 嗨,谢谢你的回答,但这并没有按截止日期排序
  • 为我的答案添加了排序。目前它将 null 放在顶部,如果这是您想要的结果,那么没有问题
  • 非常整洁。赞成。我最后的唯一评论:sort() 改变源数组,因此将其应用于源数组浅拷贝(即[...collection].sort(...)会更安全。
  • 不,但这并不能回答我的问题。请检查我的问题我正在寻找的结果。您的结果将集合排序回 callId...所以它显示 1, 2 , 3
  • id的顺序应该是,3,2,1...,id 2下的数据也需要排序,让有deadline的对象优先。
猜你喜欢
  • 1970-01-01
  • 2021-08-13
  • 2014-06-20
  • 2019-01-08
  • 2012-05-02
  • 1970-01-01
  • 1970-01-01
  • 2018-03-18
  • 2022-06-17
相关资源
最近更新 更多