【问题标题】:Comparison of two lists in HaskellHaskell中两个列表的比较
【发布时间】:2016-04-01 07:25:27
【问题描述】:

我在 Haskell 中有两个列表。

原始列表:["hello", "HELLO", "world", "WORLD"]

仅大写列表:["HELLO", "WORLD"]

你能帮我创建一个函数,它应该返回一个包含两个列表交集索引的列表。

我可以通过这样做获得第一个索引:

让 upperIndex = findIndices(==(onlyUpper !! 0)) 原始

但是,这只适用于一个实例,在这种情况下,我只能在原始列表中获取“HELLO”的索引,但我想获取所有这些。

对于这个例子,答案应该是:[1,3]

【问题讨论】:

  • 你很亲密。想想你会想给findIndices什么样的谓词。如果我们有upperIndex = findIndices (\x -> _) original,你应该用什么样的条件替换_?如果该条件为真,这意味着什么?
  • 我是初学者,老实说不知道:(

标签: list haskell comparison mask


【解决方案1】:

编辑:David Young 建议的另一个版本是

findIndicesIn xs ys = findIndices (`elem` ys) xs

我更喜欢下面的解决方案。


如果我理解正确,您有两个列表。打电话给他们xsys。您想在xs 中找到ys 中每个元素的索引。如果ys 中的元素不包含在xs 中,您没有提及您要做什么,所以我将为您选择合理的东西。这里是:

findIndicesIn :: Eq a => [a] -> [a] -> [Maybe Int]
findIndicesIn xs ys = map (`elemIndex` xs) ys

elemIndex :: Eq a => a -> [a] -> Maybe Int 查找列表中给定元素的索引(与(==) 相比)。如果元素不存在,则返回 Nothing。为了找到所有索引,我们映射ys 中的每个元素,并尝试使用elemIndexxs 中找到它。为了简洁,使用节语法代替flip elemIndex xs\y -> elemIndex y xs

结果是Maybe Int 的列表,表示ys 中每个元素在xs 中的可能 索引。请注意,如果您不跟踪丢失的元素,则结果列表中的索引位置将不再对应于 ys 中元素的位置。

你也可以用更少的点来写这个

findIndicesIn :: Eq a => [a] -> [a] -> [Maybe Int]
findIndicesIn xs = map (`elemIndex` xs)

YMMV 哪个更清楚。两者是等价的。这个版本是非常可读的IMO。你可以更进一步,写

findIndicesIn = map . flip elemIndex

但我个人觉得这不太可读。又是 YMMV。

【讨论】:

  • 那么,为什么我得到 "just 1" 、 "just 3" 而不是 1 和 3?
  • 我发现它是另一种数据类型,所以我使用“map fromJust xs”将其转换为 Int。谢谢你的回答,它也很完美,而且更短!!!
  • @Orkun 不要那样做。如果在第一个列表中找不到元素,它将导致您的程序崩溃。你会得到Just 1Just 3,因为不能保证第二个列表中的元素会在任意列表中找到,Maybe 会处理可能的失败。
  • 因为第二个列表是从第一个列表派生的。具体来说,我从原始列表中获取大写字符串元素。所以它不可能找不到第二个列表。
  • 你可以通过继续使用findIndices来避免Maybe值。
【解决方案2】:
let upperIndex original onlyUpper = helper original 0 where helper [] _ = []; helper (x:xs) i = if elem x onlyUpper then i:(helper xs (i+1)) else helper xs (i+1)

使用示例:

Prelude> upperIndex ["hello", "HELLO", "world", "WORLD"] ["HELLO", "WORLD"]
[1,3]

【讨论】:

  • 工作完美,谢谢:) 我不明白为什么人们给减号。对此感到抱歉:(
  • 这个答案应该解释它为什么以及如何工作。
  • 哦,我明白了。但他为我付出了努力,我很感激。再次感谢您,先生。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-28
  • 1970-01-01
  • 2011-06-19
  • 2013-03-03
相关资源
最近更新 更多