list - Haskell - 如果否则返回干净的元组

标签 list haskell tuples

如果第一个元组的第二个元素与第二个元组的第一个元素相同,我的家庭作业是将两个元组分组到一个列表中。然后,如果第一个元组是 (a, b)第二个是 (b, c) ,元组 (a, c)必须添加到结果列表中。

我编写了第一个函数,它接收带有一个元组的元素和带有多个元组的第二个列表,并将每个列表进行比较。

这个正确地工作:

c1 = ("a","x")
d1 = [ ("x","b"), ("z","c"), ("x","b"), ("z","c")
     , ("x","b"), ("z","c"), ("x","b"), ("z","c") ]

getByOne c1 a1 = filter (/=[])
  [ if (fst  (last(take n a1))) == (snd c1)
    then [((fst c1),  (snd  (last(take n a1))))]
    else  [] | n <- [1..(length a1) ] ]

输出:
[ [("a","b")], [("a","b")], [("a","b")], [("a","b")] ]

但问题是我不能把 if then 和 else 语句扔进简单的元组,所以我创建了一个新列表。在这个“解决方法”的最后,我得到了 list in list in list 等等。此外,如果输出列表更大,列表中的列表就会更多。

有什么方法可以只传递元组或空元组,或者我应该以某种方式对论文列表进行分组?

最佳答案

您可以使用扁平化结果

concat :: [[a]] -> [a]

那么你甚至不需要filter (/=[]) - 顺便说一下,条件 (/= [])写得更地道not . null , 自 null测试不会施加 Eq对其论点的约束(您在这里已经有了一个,所以这只是一个习语问题)。

此外,last (take n a1)就是 n a1 的第 - 个元素如果 1 <= n <= length a1 .由于您施加了该限制,因此可以更简洁地表示为 a1 !! (n-1)
然后你在结构上
getByOne c1 a1 = concat $ [something c1 (a1 !! i) | i <- [0 .. length a1 - 1]]

(我已将索引移至索引 i ),这更清晰,更有效地表示为
getByOne c1 a1 = concat $ map (something c1) a1

如果您更喜欢列表解析而不是 map ,你也可以写成
getByOne c1 a1 = concat [something c1 x | x <- a1]

在你的情况下,使用 alist-comprehension 生成器中的模式匹配能力,给了我们
getByOne (f,s) a1 = concat [ if a == s then [(f,b)] else [] | (a,b) <- a1]

这是更短,更易读。而不是使用 if condition then [element] else []concat ,更好的是在列表理解中使用条件,
getByOne (f,s) list = [(f,b) | (a,b) <- list, a == s]

这是简短而清晰的。

关于list - Haskell - 如果否则返回干净的元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13217546/

相关文章:

haskell - 无可辩驳的模式不会在递归中泄漏内存,但为什么呢?

haskell 折叠玫瑰树路径

swift - 无法理解 Swift Tuple 比较

pipe - 如何在 Julia 中使用带有元组和匿名函数的管道运算符?

haskell - 将 chr 的输出格式更改为十六进制

reactjs - Typescript:没有重复项的元组

java - 图像图标列表

python - 在 Python 中按键对字典列表进行排序

c# - 不同类型的列表列表

python - python 列表的子集基于同一列表的元素组,pythonically