Haskell:删除最大的列表

Kev*_*337 3 haskell list

我有一个列表列表,以及一个返回包含最多项目的列表的函数:

extract ::[Plateau]->Plateau

extract(x:xs) 
  |x==maximumBy(compare `on` length)(x:xs)=x 
  |otherwise = extract(xs)
extract []=[""]
Run Code Online (Sandbox Code Playgroud)

现在我需要一个函数来获取相同的函数[Plateau]并返回一个[Plateau]删除了之前最大的函数:

prune::[Plateau]->[Plateau]
prune(x:xs)
  |x < (maximumBy(compare `on` length)(x:xs)=x : prune (xs)
  |x>=maximumBy(compare `on` length)(x:xs)=[]
prune [] = [] 
Run Code Online (Sandbox Code Playgroud)

我也打电话给修剪,sortBy以确保最大的列表是最后一个:

(extract . prune) (sortBy(compare `on` length)(plateaus))
Run Code Online (Sandbox Code Playgroud)

这开始正常工作.我的列表plateaus看起来像:

plateaus = ["01000"], ["01010", "11010", "10010"] ["00101"], ["01101", "01001"]]
Run Code Online (Sandbox Code Playgroud)

在这里排序:

 [["01000"], ["00101"], ["01101", "01001"], ["01010", "11010", "10010"]]
Run Code Online (Sandbox Code Playgroud)

现在,我的函数prune正在返回一个列表

[["01000"], ["00101"]]
Run Code Online (Sandbox Code Playgroud)

这告诉我,由于某种原因Haskell认为

["01101", "01001"] >= ["01010", "11010", "10010"]
Run Code Online (Sandbox Code Playgroud)

当我可以清楚地看到2> = 3不是真的.

为什么是这样?

Nat*_*ate 8

这样的事情可能是一个更简单的选择,也许:

prune :: [Plateau] -> [Plateau]
prune s@(w:x:xs) = filter ( /= maxplateau ) s
    where maxplateau = maximumBy (compare `on` length) s
prune _ = []
Run Code Online (Sandbox Code Playgroud)

这依赖于Haskell的几个不错的部分.

第一个是模式匹配 - 你在你的问题和你之前的问题中使用了这个 - 在这里,我更进一步,要求一个至少有两个元素的列表,wx.这允许直通案例处理空条目和单条目列表情况,这应该(基于您提供的代码)导致相同的事情:空列表.

第二种是使用@符号,AKA 作为模式.我在回答你之前的问题时向你展示了这一点.虽然只是语法糖,而不是必需的,但它可以使代码更具可读性.

第三种是currying,有时称为"部分功能应用".在我的例子中,我使用了什么来学习Haskell 使用部分调用部分应用中缀函数(你应该阅读整个部分 - 非常具有形成性,能很好地解决Haskell语言的一个支柱(事实上,如果你真的喜欢或想要获得一个良好的初学者对Haskell的掌握,我会读到学习你的Haskell封面,因为它太棒了)).无论如何,那就是我用的东西( /= maxplateau ); 通常,中缀函数/=接受两个相同类型的参数,并返回Bool- 通过括在括号中并在一侧提供表达式,我已部分应用它.这产生一个Plateau参数的函数,这对于提供Plateaus 列表上的过滤函数是完美的.

最后,在我的编辑中,我稍微改变了我的答案以使用where关键字.我这样做只是为了让部分应用更加清晰.我鼓励你where在学习哈斯克尔的哪个部分阅读更多信息(你能告诉我有偏见吗?:^))


GS *_*ica 6

列表比较是词典,而不是长度.所以你得到你看到的结果,因为"01101"> ="01010",这又是出于同样的原因 - 两个字符串的前两个字符是相等的,第一个字符的第三个字符大于第三个字符第二.

  • 你可以使用groupBy`on`长度来收集所有相同长度的东西并一起处理它们. (2认同)