【问题标题】:Reorder array based on values根据值重新排序数组
【发布时间】:2020-06-17 04:13:03
【问题描述】:

我有一个包含类的数组(该类称为Note),在这些类中是基本值。两个重要的值是Note.Pinned(布尔值,无论是否固定)和Note.Modified(上次编辑时的时间戳)。

我想按Modified 时间戳对这个类数组进行排序,然后重新排序,使Pinned 注释在这个列表的顶部。

我已经试过整理笔记了。

const SortedNotes = Notes.sort((a, b) => a.Modified > b.Modified);

Notes 是带有类的数组。

但是,有没有更好的方法来重新排列这个数组?或者这是我唯一可以使用的方法?

SortedNotes.filter(n => n.Pinned).concat(SortedNotes.filter(n => !n.Pinned));

以上方法可行,我知道我可以使用Array.prototype.partition,那么还有其他方法吗?

谢谢

【问题讨论】:

  • 请注意:sort 就地排序并修改现有数组。
  • 为什么不对将固定键发送到顶部的笔记再次排序?
  • 如果 Modified 实际上是 Date 类型,而 Pinned 是布尔值,这应该可以工作 -> sort((a, b) => Number(b.Pinned) - Number(a.Pinned) || a.getTime() - b.getTime()) 在排序术语中它被称为复合索引排序。
  • (a, b) => a.Modified > b.Modified 是一个天生不稳定的排序返回值。
  • @Keith 这是一个有趣的声明,Number(b.Pinned)。我会试试这一切是如何工作的,谢谢你的回答!

标签: javascript arrays node.js sorting


【解决方案1】:

您可以将固定排序要求添加到排序中:

const arr = [{
    pinned: false,
    modified: 7
  },
  {
    pinned: false,
    modified: 6
  },
  {
    pinned: true,
    modified: 2
  },
  {
    pinned: false,
    modified: 4
  },
  {
    pinned: true,
    modified: 1
  },
  {
    pinned: true,
    modified: 8
  },
  {
    pinned: false,
    modified: 3
  },
]

arr.sort((a, b) => {
  if (a.pinned != b.pinned)
    return a.pinned ? -1 : 1;
  return b.modified - a.modified;
})

console.log(arr)

只要对相同的两个给定参数执行排序函数返回相同的结果,排序就可以正常工作。知道了这一点,您可以处理固定状态不同的两种状态,然后仅当固定状态相同时才按修改排序。

【讨论】:

  • 我已经对其进行了编辑,以删除每次调用所需的检查次数。现在是:如果固定状态不同并且第一项已固定,则将其放在第二项之前,否则将其放在之后,否则按正常排序。
  • 如果你想要更短的版本,试试这个 -> arr.sort((a,b)=>(b.pinned|0)-(a.pinned|0)||b.modified-a.modified);
【解决方案2】:

您可以按多个条件排序:

const SortedNotes = Notes.sort((a, b) => {
  if (a.Pinned == b.Pinned) {
    if (a.Modified > b.Modified) return -1;
    if (a.Modified < b.Modified) return 1;
  } else {
    return a.Pinned ? -1 : 1;
  }
});

a.Pinned == b.Pinned &amp;&amp; a.Modified == b.Modified 的缺失分支将返回 undefined,而这又会被解释为相等。

顺便说一句,数组Notes 本身已经被修改了,所以SortedNotesNotes 将表现出相同的顺序;当然,分配给const 变量不会有什么坏处。

【讨论】:

    【解决方案3】:

    也许不是最好的解决方案,但这应该可以帮助您朝着正确的方向前进。 这会对数组进行排序,以便注释按日期降序排列,固定的位于顶部。

    与其他(更好的)答案不同,这具有 O(2n) 的排序复杂性,因此请记住这一点。

    const notes = [
      {
        text: "foo",
        modified: 1583337610387,
        pinned: false
      },
      {
        text: "bar",
        modified: 1583337610388,
        pinned: true
      },
      {
        text: "baz",
        modified: 1583337610389,
        pinned: false
      },
      {
        text: "qux",
        modified: 1583337610390,
        pinned: true
      }
    ];
    
    const sortedNotes = [...notes];
    sortedNotes.sort((a, b) => a.modified > b.modified ? -1 : 1);
    sortedNotes.sort((a, b) => (a.pinned === b.pinned) ? 0 : a.pinned ? -1 : 1);
    console.log(sortedNotes);

    【讨论】:

      【解决方案4】:

      短一点,你可以试试

      const SortedNotes = Notes.sort((a, b) => {
          if (a.Pinned > b.Pinned)
             return 1;
          if (a.Pinned == b.Pinned) 
             return a.Modified > b.Modified;
          return -1;
      })
      

      【讨论】:

      • 此比较函数将返回相同的 a.Modified == b.Modified 以及 a.Modified &lt; b.Modified ...这不能保证得到很好的支持。
      【解决方案5】:

      我将@Ja͢ck 的答案编辑得更紧凑。

      const SortedNotes = Notes.sort((a, b) => {
          if (a.Pinned == b.Pinned) return a.Modified > b.Modified ? -1 : 1;
          else return a.Pinned ? -1 : 1;
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-12-27
        • 2021-11-05
        • 1970-01-01
        • 2016-07-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多