简体   繁体   English

JavaScript 对象数组按特定属性排序,然后按自定义优先级值分组

[英]JavaScript array of objects sort by specific property and then group by custom priority values

I have array of objects and my requirement was to group users by status (online users should come first) while sort grouped users by name.我有一组对象,我的要求是按状态对用户进行分组(在线用户应该排在第一位),同时按名称对分组的用户进行排序。 I am able to achieve result but here I am using lodash concat function separately.我能够实现结果,但在这里我单独使用 lodash concat函数。 Can anyone help to use it along with chain function?任何人都可以帮助将它与功能一起使用吗?

Code:代码:

  import _ from 'lodash';

  const { online = [], offline = [] } = _.chain(users)
    .sortBy([(e) => _.toLower(e.name)])
    .groupBy((e) => e.status)
    .value();
  const result = _.concat(online, offline);
  console.log('grouped users sorted by name => ', result);

Input:输入:

let users = [
    {
        'name': 'C',
        'status': 'online'
    },
    {
        'name': 'd',
        'status': 'online'
    },
    {
        'name': 'a',
        'status': 'offline'
    },
    {
        'name': 'b',
        'status': 'online'
    },
    {
        'name': 'f',
        'status': 'offline'
    },
    {
        'name': 'e',
        'status': 'offline'
    }
];

Output:输出:

[
    {
        'name': 'b',
        'status': 'online'
    },
    {
        'name': 'C',
        'status': 'online'
    },
    {
        'name': 'd',
        'status': 'online'
    },
    {
        'name': 'a',
        'status': 'offline'
    },
    {
        'name': 'e',
        'status': 'offline'
    },
    {
        'name': 'f',
        'status': 'offline'
    }
]

Thanks谢谢

You can use reduce , filter & sort .您可以使用reducefiltersort Create a separate array and add the status in order you want the final array to be be.创建一个单独的数组并按照您希望最终数组的顺序添加状态。 Then inside the reduce callback use filter to get the elements of that status and use sort to sort the elements in order of name然后在reduce回调中使用filter获取该状态的元素并使用sortname顺序对元素进行排序

 let sortStatus = ['online', 'offline']; let users = [{ name: 'C', status: 'online' }, { name: 'd', status: 'online' }, { name: 'a', status: 'offline' }, { name: 'b', status: 'online' } ]; let data = sortStatus.reduce((acc, curr) => { acc.push( ...users .filter(item => item.status === curr) .sort((a, b) => a.name.localeCompare(b.name)) ); return acc; }, []); console.log(data);

You can do this easily without lodash too.您也可以在没有 lodash 的情况下轻松完成此操作。

You can use a customized sort function when calling the sort() function of an array.您可以在调用数组的sort()函数时使用自定义排序函数。 Create a sort string including a 0 for online users and a 1 for offline users followed by the name.创建一个排序字符串,其中在线用户为 0,离线用户为 1,后跟名称。 Then use this sort string in the comparison.然后在比较中使用这个排序字符串。

 let users = [{ 'name': 'C', 'status': 'online' }, { 'name': 'd', 'status': 'online' }, { 'name': 'a', 'status': 'offline' }, { 'name': 'b', 'status': 'online' }, { 'name': 'f', 'status': 'offline' }, { 'name': 'e', 'status': 'offline' } ]; users.sort((a, b) => { let sortStringA = (a.status.toUpperCase() == 'ONLINE' ? 0 : 1) + a.name.toUpperCase(); let sortStringB = (b.status.toUpperCase() == 'ONLINE' ? 0 : 1) + b.name.toUpperCase(); if (sortStringA < sortStringB) { return -1; } if (sortStringA > sortStringB) { return 1; } return 0; }); console.log(users);

If You can correct input:如果您可以更正输入:

 let users = [ { name: 'C', status: 'online' }, { name: 'd', status: 'online' }, { name: 'a', status: 'offline' }, { name: 'b', status: 'online' }, { name: 'f', status: 'offline' }, { name: 'e', status: 'offline' } ]; const sorted = users.sort((a, b) => { if (a.name.toLowerCase() < b.name.toLowerCase()) { return a.status.toLowerCase() < b.status.toLowerCase() ? 1 : -1; } return b.status.toLowerCase() < a.status.toLowerCase() ? -1 : 1;; }) console.log(sorted )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM