【问题标题】:Haskell List comprehension and `group`Haskell 列表理解和“组”
【发布时间】:2021-01-12 08:49:50
【问题描述】:

输入:

funcA [((0,'x'),1),((0,'y'),3),((1,'y'),3),((1,'z '),3),((2,'x'),2),((2,'y'),2)]

输出

[(0, 1, "x"), (0, 3, "y"), (1, 3, "yz"), (2, 2, "xy") ]

我正在尝试按起始节点和目标节点进行分组,然后是 concat 所有边缘名称(值如 'x''y'...)。所以输出顺序是[(start, end, "concat val"), ...]

如何用 Haskell 语言编写funcA??

我尝试了groupBy,列表理解,map 函数,但无法弄清楚。

【问题讨论】:

  • funcA [((0,'a'),0),((1,'b'),1),((0,'c'),0)] 应该输出什么?我想知道需要分组的值是否在输入列表中总是相邻的。
  • 我是的,所以,我需要先对其进行排序

标签: list haskell grouping list-comprehension higher-order-functions


【解决方案1】:

您可以将funcA 定义为:

import Data.Function (on)
import Data.List (groupBy)

funcA :: Eq a => [((a,b),a)] -> [(a,a,[b])]
funcA =
  map (\s@(((x,y),_):_) -> (x, y, map snd s))
  . groupBy ((==) `on` fst)
  . map (\((x,v),y) -> ((x,y),v))

给定名单:[((0,'x'),1),((0,'y'),3),((1,'y'),3),((1,'z'),3),((2,'x'),2),((2,'y'),2)]

  • 链尾的map将坐标连接成一个元组:

    [((0,1),'x'),((0,3),'y'),((1,3),'y'),((1,3),'z'),((2,2),'x'),((2,2),'y')]

  • groupBy 坐标组:

    [[((0,1),'x')],[((0,3),'y')],[((1,3),'y'),((1,3),'z')],[((2,2),'x'),((2,2),'y')]]

  • 第一个map 将具有相同坐标的字符组合成具有该坐标的字符串。

【讨论】:

  • map (\ s@(((x,y),_):_) -> (x, y, map snd s)) 也应该可以完成这项工作。
  • (让我恼火的主要是(0,0,[]) 中的零。如果有的话,应该使用undefineds。但当然正如所写的那样,折叠只是重新-实现map。)
  • @WillNess:感谢您的反馈。你说得对,(0,0,[]) 很丑。您使用map snd 等的建议要好得多。我已经相应地更新了。
  • ... 它现在可以与任何Eq 类型一起使用,而不仅仅是Int(Num,Eq)。 :)
  • @WillNess:谢谢,我也这样做了。 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多