Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 在Haskell中将列表分组为n个元素的列表_List_Haskell - Fatal编程技术网

List 在Haskell中将列表分组为n个元素的列表

List 在Haskell中将列表分组为n个元素的列表,list,haskell,List,Haskell,库中是否有对列表的操作,使n个元素组成一组?例如:n=3 groupInto 3 [1,2,3,4,5,6,7,8,9] = [[1,2,3],[4,5,6],[7,8,9]] 如果没有,我该怎么做?在上快速搜索显示没有这样的功能。另一方面,答复说,split包中有一个名为chunksOf 但是,你可以自己做 group :: Int -> [a] -> [[a]] group _ [] = [] group n l | n > 0 = (take n l) : (gro

库中是否有对列表的操作,使n个元素组成一组?例如:n=3

groupInto 3 [1,2,3,4,5,6,7,8,9] = [[1,2,3],[4,5,6],[7,8,9]]
如果没有,我该怎么做?

在上快速搜索显示没有这样的功能。另一方面,答复说,
split
包中有一个名为
chunksOf

但是,你可以自己做

group :: Int -> [a] -> [[a]]
group _ [] = []
group n l
  | n > 0 = (take n l) : (group n (drop n l))
  | otherwise = error "Negative or zero n"
当然,可以删除一些括号,我留在这里是为了理解代码的作用:

基本情况很简单:只要列表为空,就返回空列表

递归案例首先测试
n
是否为正。如果
n
0
或更低,我们将进入一个无限循环,我们不希望这样。然后我们使用and将列表分成两部分:
take
返回第一个
n
元素,而
drop
返回其他元素。然后,我们将第一个
n
元素添加到通过将我们的函数应用于原始列表中的其他元素而获得的列表中


除了其他类似功能外,此功能还可以在流行软件包中找到

这通常被称为“chunk”,是不在
base
中最常提到的列表操作之一。该软件包提供了这样一种操作,即复制和粘贴haddock文档:

 > chunksOf 3 ['a'..'z']
 ["abc","def","ghi","jkl","mno","pqr","stu","vwx","yz"]

此外,根据我的意愿,hoogle只搜索一小部分库(GHC或HP提供的库),但您可以使用
+PKG_NAME
-hoogle with
Int->[a]->[[a]]+split
显式地向搜索中添加包。有些人使用Haoo就是为了这个原因。

正如Mihai所指出的,你可以自己写一本。但我会使用该函数,因为它不需要像
take
-
drop
组合那样在输入列表上进行两次传递:

chunks :: Int -> [a] -> [[a]]
chunks _ [] = []
chunks n xs =
    let (ys, zs) = splitAt n xs
    in  ys : chunks n zs
这是一种常见的模式-通过重复迭代从种子值(在本例中是您的输入列表)生成列表。此模式在函数中捕获。我们可以将它与稍微修改过的
splitAt
版本一起使用(感谢您提供更简洁的版本):

也就是说,使用
unfover
我们生成
n
元素的块,同时我们将输入列表缩短
n
元素,并生成这些块,直到得到空列表——此时,初始输入已完全消耗


当然,正如其他人所指出的,您应该使用
split
模块中已经存在的函数。但是习惯于使用标准Haskell库中的列表处理函数总是很好的。

如果存在这样的函数,它的类型将是
Int->[a]->[[a]]
,因此您可以选择它。不过什么也没看到:@matrixprog-hoogle默认只搜索几个包,搜索更多(我认为甚至是所有的hackage)。可能与@DanielWagner-Hmm.重复。。这个答案比那个答案好。@AndrewC:我同意,不过标题很需要编辑。你是如何“导入”拆分的<代码>阴谋集团安装拆分?然后它就可以工作了,运行
ghci
或使用
ghc
编译,并确保使用了
import Data.List.Split
。如果这是在一个cablized项目中,请确保将
split
添加到构建部门。
chunks n xs=takeWhile(not.null)$unfover(Just.splitAt n)xs
)谢谢这确实是一个更优雅的实现。您的错误消息是错误的
n
在这种情况下不是负的,它不是正的。
cabal install split
chunks :: Int -> [a] -> [[a]]
chunks _ [] = []
chunks n xs =
    let (ys, zs) = splitAt n xs
    in  ys : chunks n zs
chunks n = takeWhile (not . null) . unfoldr (Just . splitAt n)