Ответ 1
Для полноты, версия, которая работает как с пустыми, так и с бесконечными списками.
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]
У меня есть список a
,
let a = ["#","@","#","#"]
Как я могу повернуть @
два пробела, чтобы они закончились так?
["#","#","#","@"]
Я думал, что это может сработать,
map last init a
но, возможно, синтаксис должен быть другим, потому что карта может работать только с одной функцией?
Для полноты, версия, которая работает как с пустыми, так и с бесконечными списками.
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]
Простое решение с использованием функции cycle
, которая создает бесконечное повторение входного списка:
rotate :: Int -> [a] -> [a]
rotate n xs = take (length xs) (drop n (cycle xs))
затем
> rotate 2 ["#","@","#","#"]
["#","#","#","@"].
Почему это осложняется?
rotate n xs = bs ++ as where (as, bs) = splitAt n xs
Я очень новичок в haskell, поэтому ответ MGwynne был понятен. В сочетании с комментарием предлагающим альтернативный синтаксис, я попытался заставить его работать в обоих направлениях.
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 []
.
Начинающая попытка:
myRotate :: Int -> [String] -> [String]
myRotate 0 xs = xs
myRotate n xs = myRotate (n-1) (last xs : init xs)
Не очень быстро для больших списков, но достаточно:
rotate :: Int -> [a] -> [a]
rotate n xs = iterate rot xs !! n
where
rot xs = last xs : init xs
Например:
> rotate 2 ["#","@","#","#"]
["#","#","#","@"]
rotate :: Int -> [a] -> [a]
rotate n xs = drop k xs ++ take k xs
where k = length xs - n
Эта функция вращается на n мест справа.
rotate :: Int -> [a] -> [a]
rotate = drop <> take