2015-12-27 80 views
-4

Haskell中有两个列表。Haskell中两个列表的比较

原版:[ “你好”, “你好”, “世界”, “世界”]

只有大写列表:[ “HELLO”, “世界”]

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

我可以这样做,得到的第一个指标:

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

然而,这只能用于一个实例,在这个我只能在原始列表中获得“HELLO”的索引,但我想要获得所有这些索引。

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

+0

你非常接近。想一想你想给'findIndices'做什么样的谓词。如果我们有'upperIndex = findIndices(\ x - > _)original',应该用什么样的条件替换'_'?如果这种情况是真的,那么这意味着什么? –

+0

我是初学者,老实说不知道:( – Orkun

回答

0

编辑:由David杨建议另一个版本是

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

其中I p请参阅下面的解决方案。


如果我理解正确,你有两个列表。打电话给他们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) 

因人而异上哪一个更明确的写使用更少点。两者都是相同的。这个版本是相当可读的IMO。你可以更进一步,并写

findIndicesIn = map . flip elemIndex 

但个人而言,我觉得这可读性较差。 YMMV再次。

+0

那么,为什么我会得到“只有1 “,”只是3“而不是1和3? – Orkun

+0

我发现它是另一种数据类型,所以我使用”map fromJust xs“将它转换为Int。谢谢你的回答,它的工作原理也很完美,并且缩短了很多!!! – Orkun

+0

@Orkun不要这么做,如果在第一个列表中没有找到元素,它会导致程序崩溃,你会得到'Just 1'和'Just 3',因为不能保证第二个列表将在任意列表中找到,'Maybe'处理可能的失败 –

-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] 
+0

作品无瑕谢谢:)我不明白为什么人们给减。对不起,关于这个:( – Orkun

+3

这个答案应该有一个解释为什么以及它是如何工作的 –

+0

噢,我明白了,但是他为我付出了努力,我很感谢你,再一次感谢你, – Orkun