【问题标题】:Sort a list of tuples by their second element and absolute value按第二个元素和绝对值对元组列表进行排序
【发布时间】:2014-10-31 07:52:02
【问题描述】:

如何排序这个列表

[("apple",3),("apple",-2),("pear",1)]

按元组中的第二个元素,按绝对值,所以

[("pear",1),("apple",-2),("apple",3)]

【问题讨论】:

  • sortWith f == sortBy (comparing f) == sortBy (compare on` f)`。它们都完全相同,一件事。 decorate-sort-undecorate 模式是实质性的,尽管可以进一步讨论。
  • @WillNess 我的其他答案是否与您在评论中指出的方向一致?
  • @Boris 通常需要使用 costly “key”(即“to-sort-by”)功能;这里不需要,因为只有abs 会重新计算多次,而且很便宜。您的第二个功能很接近,但最好使用sortBy (comparing fst3) ... where fst3(a,_,_)=a 而不是sort,以消除其他字段对排序的任何影响(对于重复键)。此外,不必使用fst3,通常您会以嵌套方式排列数据,因此可以使用普通的fst

标签: sorting haskell tuples


【解决方案1】:

怎么样:

import Data.Ord (comparing)
import Data.List (sortBy)

sortBy (comparing (\(x,y) -> abs y)) [("apple",3),("apple",-2),("pear",1)]

这是我用 Haskell 写的第一件事,所以如果有人指出为什么这是错误的以及如何改进它,我不介意。

在@WillNess 对原始问题的评论之后,这是一个尝试使用“装饰-排序-取消装饰”模式的版本:

[ (a,b) | (foo,a,b) <- sort [ (abs b,a,b) | (a,b) <- x ] ]

其中 x 是原始列表。

【讨论】:

  • 除非你想像@jamshidh's answer那样无点,否则我唯一想改变的是删除y周围的括号。
  • @ØrjanJohansen 感谢您的有用评论!
  • 为了澄清“无意义”评论,您可以改为写comparing (abs . snd)comparing $ abs . snd。但我同意,你的代码很棒。
  • @MichaelSnoyman 是的,经过一番谷歌搜索,我有点明白“无点”的含义。但是,我不知道为什么一个版本应该优于另一个版本:关于“惯用”代码、可读性、用例等。无论如何,这是我自己想弄清楚的。跨度>
  • 这真的只是一个品味问题,而且对此的品味实际上相差很大。您写的内容是完全有效的、惯用的 Haskell 代码 imo。
【解决方案2】:
import Data.Function
import Data.List

sortBy (compare `on` abs . snd) [("apple",3),("apple",-2),("pear",1)]

【讨论】:

    【解决方案3】:

    这是一个转述的方法:

    import Data.List
    import GHC.Exts
    
    sortWith (abs . snd) [("apple",3),("apple",-2),("pear",1)]
    

    您可以将它应用于任何需要转换键容器进行排序的问题。

    在您的情况下,abs . snd 函数用于将("Foo", -5) 转换为5,然后按新键排序。

    【讨论】:

      猜你喜欢
      • 2012-03-08
      • 2012-03-13
      • 1970-01-01
      • 1970-01-01
      • 2015-06-16
      • 2011-05-21
      • 2022-08-18
      • 2016-03-17
      • 1970-01-01
      相关资源
      最近更新 更多