【问题标题】:Sort a list of pairs using sort Haskell使用 sort Haskell 对对列表进行排序
【发布时间】:2012-05-04 07:04:07
【问题描述】:

我有一个函数(频率),它计算列表中每个不同值在该列表中出现的次数。例如,

frequency "ababca" 

应该返回:

[(3, 'a'), (2, 'b'), (1, 'c')].

这工作正常,但现在我需要使用此函数使用列表列表中的第一个元素对列表进行排序。

results   :: [Party ] -> [(Int, Party)]
results  xs = ??? frequency (sort xs) ??? 

所需输出示例:

[(1, "Green"), (2, "Red"), (3, "Blue")]

以上不起作用,我不知道我能做什么。

使用常规的“排序”

在此先感谢您。

【问题讨论】:

  • 请注意,您使用分号,而 Haskell 使用逗号。

标签: haskell


【解决方案1】:
import Data.Function (on)
import Data.List (sortBy)

results xs = sortBy (compare `on` fst) (frequency xs)

-- or, if you prefer
results xs = sort (frequency xs)

onsortBycomparefst 的文档链接。

不同之处在于sort 按每对的第一个元素的升序排序,用第二个元素打破平局,而sortBy (compare `on` fst) 明确只查看每对的第一个元素。

【讨论】:

  • 我怎样才能使用常规的“排序”来做和上面一样的事情?
  • 你可以用(comparing fst)代替(compare `on` fst)
【解决方案2】:

如果您只能使用sort 而不能使用sortBy(出于某种原因!),那么您需要确保项目属于Ord 实例的类型。碰巧的是,所有元组(最大大小为 15)都有 Ord 实例,前提是 所有 元组中的位置也有 Ord 实例。

您给出的(1, "Green"), (2, "Red"), (3, "Blue")] 的示例应该可以很好地排序(尽管颠倒了),因为IntString 都有Ord 实例。

但是,在代码 sn-p 中,您还提到了 Party 类型,但实际上并未说明它是什么。如果它不仅仅是 String 之类的别名,您可能必须为其定义一个 Ord 实例,以满足元组的内置 Ord 实例。

您可以让 Haskell 为您创建实例,在声明类型时使用 deriving

 data Party = P1 | P2 | P3 | P4 -- e.g.
     deriving (Eq,Ord)

或自己声明:

 instance Ord Party where
     -- you don't care about the ordering of the party values
     compare a b = EQ   

但是,正如 dave4420 所说,最好只使用 sortBy,所以我会这样做,除非你有特定的理由不这样做(即这是一个有限制的班级作业)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-28
    • 1970-01-01
    • 2020-10-24
    • 1970-01-01
    • 1970-01-01
    • 2012-11-30
    • 2016-08-03
    相关资源
    最近更新 更多