Как из списка точек получить два списка координат?

Рейтинг: 2Ответов: 2Опубликовано: 18.04.2023

Имея набор точек X, Y на новых линиях строки, как короче всего получить два списка X и Y отдельно? Или, что то же - имея 1 список, как получить два списка с элементами на чётных и нечётных позициях?

"1 2\n3 4\n" -> [[1, 3], [2, 4]]
[1, 2, 3, 4] -> [[1, 3], [2, 4]]

Из 1 инпута можно получить второй через words. Для второго инпута можно сделать

splitOnPos [] = [[], []]
splitOnPos (x1:x2:xs) = [x1:odds, x2:evens]  
    where [odds, evens] = splitOnPos xs

Но может можно как-то короче сделать для первого? Или укоротить решение для второго? Может быть как-то можно одновременно применить head и last после map words . lines?

Ответы

▲ 0Принят
ghci> import Data.List (transpose)
ghci> transpose . map words . lines $ "1 2\n3 4\n"
[["1","3"],["2","4"]]

Правда тут на выходе список строк, как и в вашем варианте

ghci> zipWith ($) [map head, map last] . repeat . map words . lines $ "1 2\n3 4\n"
[["1","3"],["2","4"]]

так что

ghci> transpose . map (map read . words) . lines $ "1 2\n3 4\n" :: [[Int]]
[[1,3],[2,4]]

Ну и если дальше развивать ваш вариант

ghci> mapM map [head, last] . map words . lines $ "1 2\n3 4\n"
[["1","3"],["2","4"]]
ghci> mapM (map . (read .)) [head, last] . map words . lines $ "1 2\n3 4\n" :: [[Int]]
[[1,3],[2,4]]

для второго примера

ghci> import Data.List.Split (chunksOf)
ghci> transpose . chunksOf 2 $ [1, 2, 3, 4]
[[1,3],[2,4]]
▲ 1

Такой вариант есть:

zipWith ($) [map head, map last] . repeat . map words . lines