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

标签 haskell

让我们考虑 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/

相关文章:

Haskell 性能 : Composition vs Application?

performance - 对于非常有状态的游戏/模拟,Haskell 状态与 C++ 相比效率如何?

haskell - 函数组合的点表示法

haskell - 在 Haskell 中构建循环列表的最便宜的方法

haskell - Reactive的替代库更简单? ( haskell )

parsing - 在 Haskell 中正确解析 uu-parsinglib 中的行缩进

haskell - ByteString 的 chunksOf 模拟?

haskell - 如何从Haskell链接到C#(即托管)DLL?

haskell - 为什么用 -fllvm 编译这个 Haskell 程序会产生不同的结果?

haskell - Parsec - 'many' 和错误消息