从列表中获取X个第一个元素

时间:2014-09-24 17:59:55

标签: haskell

我们考虑两个列表:["a","b","c"]["a","b","c","d","e","f"]

我想检查第一个列表是否是另一个列表的开头 我以为我可以用:

["a","b","c"] == head (splitAt (length ["a","b","c"]) ["a","b","c","d","e","f"])

不幸的是,这不起作用。还有另一种方法可以将新列表中第一个3个第一个元素从列表中删除吗?

3 个答案:

答案 0 :(得分:6)

您可以使用take来避免遍历列表两次,而不是使用zipWith。当您调用length时,首先必须遍历较短的列表,然后从较长的列表中获取那么多值,然后遍历列表,逐个元素地进行比较。更有意义的是同时遍历两个列表,在较短的列表到期时停止比较。 zipWith正好提供了此功能:

-- Definitions for `and` and `zipWith` in `Prelude`
--
-- and :: [Bool] -> Bool
-- and [] = True
-- and (x:xs) = x && and xs
--
-- zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
-- zipWith f (x:xs) (y:ys) = f x y : zipWith f xs ys
-- zipWith _ _      _      = []

sameStartingElements :: Eq a => [a] -> [a] -> Bool
sameStartingElements xs ys = and $ zipWith (==) xs ys

由于懒惰,这个定义只会遍历两个列表,并且只要其中一个列出元素就会停止。这将更有效,并且它避免了必须知道任何列表的长度。

答案 1 :(得分:3)

  

我想检查第一个列表是否是另一个列表的开头。

您可以使用Data.List模块中的isPrefixOf

答案 2 :(得分:1)

您正在寻找的功能是take。请参阅here