让我们考虑 2 个列表:["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 个第一个元素?
最佳答案
而不是使用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
由于惰性,这个定义只会遍历两个列表一次,并且一旦其中一个用完元素就停止。这会更有效率,并且避免了必须知道任一列表的长度。
关于haskell - 从列表中获取 X 个第一个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26023474/