按优先级对分组数组进行排序

时间:2020-08-06 18:29:49

标签: javascript arrays sorting

很抱歉,我的措词不好,我什至无法以友好的方式来表述,因此我将通过示例进行描述。

我有优先事项:

const priorities = new Map([
    ['lowest', 1],
    ['low', 2],
    ['high', 3],
    ['highest', 4],
])

我有一组具有组和优先级的对象:

const array = [
    {id: 1, priority: 'high'},
    {id: 2, priority: 'lowest'},
    {id: 3, priority: 'highest'},
    {id: 4, group: 1, priority: 'low'},
    {id: 5, group: 2, priority: 'low'},
    {id: 6, group: 2, priority: 'lowest'},
    {id: 7, group: 2, priority: 'low'},
    {id: 8, group: 1, priority: 'high'}
];

并且我已经将此数组分组为具有元素数组的对象:

const groups = {
    0: [{ id: 1, priority: 'high' }, { id: 2, priority: 'lowest' }, { id: 3, priority: 'highest' }], // have no highest priority for group 0
    1: [{ id: 4, group: 1, priority: 'low' }, { id: 8, group: 1, priority: 'high' }], // high
    2: [{ id: 5, group: 2, priority: 'low' }, { id: 6, group: 2, priority: 'lowest' }, { id: 7, group: 2, priority: 'low' }] // low
};

(组0除外)的优先级,它是该组中项目的最高优先级。我需要从每个组(第0组除外)中选择最高优先级,以对第0组中的组和项目从highestlowest进行排序,看起来应该是

[<highest by priority item w/o group>, ...<items from highest by priority group>, ... , <lowest by priority items>, <>]

我完全需要按group's priority + item without group priority + initial position进行排序。 例如。当前初始数组的结果:

const result = [
    { id: 3, priority: 'highest' },
    { id: 1, priority: 'high' },
    { id: 4, group: 1, priority: 'low' },
    { id: 8, group: 1, priority: 'high' },
    { id: 5, group: 2, priority: 'low' },
    { id: 6, group: 2, priority: 'lowest' },
    { id: 7, group: 2, priority: 'low' },
    { id: 2, priority: 'lowest' },
];

我该怎么做?

1 个答案:

答案 0 :(得分:2)

您可以

  • 给每个项目一个索引,以了解它们的原始顺序。 (也可能依赖于排序稳定性,但是在显式表示时更容易进行推理):

    for (const [i, o] of array.entries()) o.index = i;
    
  • 根据最高优先级和第一项给每个组一个要排序的键:

    const groupIds = Object.keys(groups).filter(g => g != 0);
    groupIds.map(g => {
      let minIndex = Infinity, maxPriority = 0;
      for (const item of groups[g])
        minIndex = Math.min(minIndex, item.index);
        maxPriority = Math.max(maxPriority, priorities.get(item.priority));
      }
      return {group: groups[g], minIndex, maxPriority};
    })
    
  • 为每个未分组的项目添加一个单项“组”:

    ….concat(groups[0].map(item => {
      return {group: [item], maxPriority: priorities.get(item.priority), minIndex: item.index};
    }))
    
  • 在对组数组进行排序之前:

    ….sort((a, b) => b.maxPriority - a.maxPriority || a.minIndex - b.minIndex)
    
  • ,然后将它们结合在一起成为结果:

    ….flatMap(({group}) => {
      return group.sort((a, b) => a.index - b.index); // might be unnecessary depending on how you built the group arrays
    });