我定义了一个列表a
,
let a = ["#","@","#","#"]
如何旋转@
两个空格,以便它最终结束?
["#","#","#","@"]
我认为这可行,
map last init a
但也许语法必须不同,因为map只能用于一个函数?
答案 0 :(得分:58)
为了完整起见,这个版本适用于空列表和无限列表。
rotate :: Int -> [a] -> [a]
rotate _ [] = []
rotate n xs = zipWith const (drop n (cycle xs)) xs
然后
Prelude> rotate 2 [1..5]
[3,4,5,1,2]
答案 1 :(得分:24)
使用cycle
函数的简单解决方案,它会创建无限重复的输入列表:
rotate :: Int -> [a] -> [a]
rotate n xs = take (length xs) (drop n (cycle xs))
然后
> rotate 2 ["#","@","#","#"]
["#","#","#","@"].
答案 2 :(得分:17)
为什么要让它变得复杂?
rotate n xs = bs ++ as where (as, bs) = splitAt n xs
答案 3 :(得分:3)
我对haskell很新,所以MGwynne's answer很容易理解。结合comment suggesting an alternative syntax,我试图让它在两个方向都有效。
rotate :: Int -> [a] -> [a]
rotate n xs = take lxs . drop (n `mod` lxs) . cycle $ xs where lxs = length xs
因此,rotate (-1) [1,2,3,4]
会为您提供与rotate 3 [1,2,3,4]
相同的结果。
我认为我必须添加这个,因为drop
ping不到0个元素什么都不做,所以我的首选答案是"错误" (至少令人困惑)结果为n
参数的负值。
这个解决方案的有趣的部分是它结合了"完整性"用于处理空列表的负旋转。感谢Haskell的懒惰,它也为rotate 0 []
提供了正确的结果。
答案 4 :(得分:2)
初学者尝试:
myRotate :: Int -> [String] -> [String]
myRotate 0 xs = xs
myRotate n xs = myRotate (n-1) (last xs : init xs)
答案 5 :(得分:1)
对于大型列表来说不是很快,但足够:
rotate :: Int -> [a] -> [a]
rotate n xs = iterate rot xs !! n
where
rot xs = last xs : init xs
例如:
> rotate 2 ["#","@","#","#"]
["#","#","#","@"]
答案 6 :(得分:0)
rotate :: Int -> [a] -> [a]
rotate n xs = drop k xs ++ take k xs
where k = length xs - n
此功能向右旋转n个位置。
答案 7 :(得分:0)
rotate :: Int -> [a] -> [a]
rotate = drop <> take