Haskell 中两个列表的比较

Comparison of two lists in Haskell

我在 Haskell 中有两个列表。

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

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

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

我可以这样得到第一个索引:

let upperIndex = findIndices(==(onlyUpper !!0)) original

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

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

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]

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

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

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


如果我没理解错的话,你有两个列表。称他们为 xsys。您想要找到 ys 中每个元素在 xs 中的索引。如果 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上哪个更清楚。两者是等价的。这个版本在我看来是非常可读的。你可以更进一步写

findIndicesIn = map . flip elemIndex

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