【问题标题】:functional non-destructive array sort功能性无损数组排序
【发布时间】:2015-05-25 04:35:57
【问题描述】:

除了克隆数组然后就地排序的原生方式之外,是否有更适合非破坏性排序的算法和现有实现?

需要在不更改源的情况下将浮点数组排序为新数组。我的搜索结果相当薄,因为大多数文献都集中在通过就地排序减少内存需求。

使用原生 sorted = [].slice().sort() 效果很好。这个问题是关于了解当内存约束被移除时是否还有其他性能排序实现,因为无论如何都需要一个新数组。

【问题讨论】:

  • “是否有任何现有的功能排序实现可用?” --- [].slice().sort() 怎么样?
  • 没有首选算法。这取决于你想如何使用它。我会选择.slice().sort()
  • 可能值得对.slice() 的性能与创建新数组并单独推送元素进行微基准测试。这可能就是您列出的库不使用按顺序构建结果数组的算法的原因。
  • 您可能应该解释一下您的意思是“更好的方法”;哪种方式更好?
  • 如果您要求首选算法,您必须指定衡量它的标准:性能?最小内存使用量?对垃圾收集器的影响最小?最紧凑的代码?最容易理解?最常用的内置函数?不说衡量标准是什么,这个问题基本上没有意义,因为“首选”没有非常具体的上下文就没有意义。例如,如果您要在 5 个提交的首选算法中评判一场比赛,那么您衡量每个提交的确切量化标准是什么?

标签: javascript arrays sorting


【解决方案1】:

有一种更简单的语法可以使用 ES6 扩展运算符对数组进行不可变排序:

[...array].sort(sortFn)

【讨论】:

  • 除了 spread 不会做深度克隆,所以如果它是一个具有多个级别的对象数组,那么你有点 SOL。
  • @robertmain,实际上,这样更好。因为排序也不会改变包含的对象。克隆包含对象会杀死其他地方的浅比较,使优化变得非常困难。
  • 我更喜欢这种方法,因为它简洁。
  • 它仍然是对克隆的就地排序(即克隆然后就地排序克隆)。问题是关于从源到目标的异地排序的潜在好处。
  • @s.meijer 很有趣!...出于这个原因,iv 总是避免在排序上进行浅层克隆,但我从来没有真正想过你没有在那种排序中改变嵌套对象的事实
【解决方案2】:

因为 cmets 已经重复了几次:

  1. shuffledArray.slice().sort() 是默认方式。
  2. 目前尚不清楚如何使用您提到的库获得更好的算法/方法。

看到非破坏性排序的动机与编写函数式代码有关,而您正在研究 Ramda...如果您还没有的话,请查看 Facebook 的 ImmutableJS 库。

尤其是Seq。 您可以开始将浮点数组存储在 Seq 中,对其进行排序,并确保原始 Seq 保持正确的顺序。 此外,它利用惰性评估。 http://facebook.github.io/immutable-js/docs/#/Seq
http://facebook.github.io/immutable-js/docs/#/Seq/sortBy

【讨论】:

  • 谢谢。我查看了 immutable-js 源代码,它还使用“克隆然后就地原生排序”,就像 underscorelodash拉姆达。由于算法文献非常关注就地排序以减少内存需求,我认为删除该约束会改变事情。到目前为止,所有的反馈都表明不是。
猜你喜欢
  • 2010-09-14
  • 1970-01-01
  • 2020-03-17
  • 1970-01-01
  • 2011-11-01
  • 2021-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多