Управление списком с использованием сопоставления с образцом - PullRequest
0 голосов
/ 06 мая 2019

Я хочу написать функцию, которая принимает список в качестве входного значения и манипулирует им следующим образом:

Шаг 1. Поместите каждые 3 элемента списка в подсписок.Если осталось менее 3 элементов, остальные элементы объединяются в конкретный подсписок, который не будет релевантным на шаге 2.

Шаг 2: Обратный порядок элементов в созданных подсписках.Первый элемент должен быть размещен в позиции третьего элемента, второй - в позиции первого элемента, а третий элемент - в позиции второго элемента.([1,2,3] преобразовано в [2,3,1])

Пример:

[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] 

-- should be transformed to 
[[2,3,1],[5,6,4],[8,9,7],[11,12,10],[14,15,13],[16,17]] 

До сих пор я нашел следующий подход для объединения каждых 3 элементов в подспискино я не совсем уверен, как изменить порядок элементов в каждом подсписке, чтобы он соответствовал требованиям.

    splitEvery :: Int -> [a] -> [[a]]
    splitEvery _ [] = []
    splitEvery n xs = as : splitEvery n bs 
        where (as,bs) = splitAt n xs

Ответы [ 3 ]

0 голосов
/ 07 мая 2019

Вы также можете достичь своей цели, используя взятие и падение

f [] = []
f xs = (take 3 xs) : f2 (drop 3 xs)
0 голосов
/ 07 мая 2019

Идиоматический Haskell будет намного лучше, чем другие ответы здесь. По сути, старайтесь всегда разрабатывать API, чтобы он содержал доказательство того, что не может быть никакого углового случая. Жесткие литералы или жесткие операции с переворотами в списках (без гарантии его длины) ВСЕГДА ПЛОХО.

{-# LANGUAGE LambdaCase #-}

divide : [a] -> [Either [a] (a,a,a)]
divide = \case
    []          -> []
    t1:t2:t3:ts -> Right (t1,t2,t3) : divide ts
    ts          -> [Left ts]

process :: [Either [a] (a,a,a)] -> [[a]]
process = fmap (flatten . flipEls) where
    flipEls = fmap $ \(t1,t2,t3) -> [t2,t1,t3]
    flatten = either id id

Теперь вы можете просто, как process . divide

0 голосов
/ 07 мая 2019

Если внутренние списки всегда состоят из 3 элементов, вы можете жестко закодировать этот факт и использовать простое решение, подобное следующему:

f :: [a] -> [[a]]
f [] = []
f (x1:x2:x3:xs) = [x2,x3,x1]:f xs
f xs = [xs]
...