#list #haskell #grouping #list-comprehension #higher-order-functions
#Список #haskell #группировка #понимание списка #функции более высокого порядка
Вопрос:
ввод:
funcA [((0,’x’),1),((0,’ у’),3),((1,’ у’),3),((1,’ z’),3),((2,’ x’),2),((2, ‘y’),2)]
вывод
[(0, 1, «x»), (0, 3, «y»), (1, 3, «yz»), (2, 2, «xy»)]
Я пытаюсь сгруппировать, начав узел и конечный узел, а затем concat
все имена ребер (такие значения, как 'x'
, 'y'
…). Таким образом, порядок вывода [(start, end, "concat val"), ...]
Как я могу написать funcA
на языке Haskell??
Я попробовал groupBy
, понимание списка, map
функцию в нем, но не смог понять это.
Комментарии:
1. Из чего следует выводить
funcA [((0,'a'),0),((1,'b'),1),((0,'c'),0)]
? Мне интересно, всегда ли значения, которые необходимо сгруппировать, находятся рядом во входном списке.2. Я да, верно, поэтому мне нужно сначала отсортировать его
Ответ №1:
Вы могли бы определить funcA
как:
import Data.Function (on)
import Data.List (groupBy)
funcA :: Eq a => [((a,b),a)] -> [(a,a,[b])]
funcA =
map (s@(((x,y),_):_) -> (x, y, map snd s))
. groupBy ((==) `on` fst)
. map (((x,v),y) -> ((x,y),v))
Учитывая список: [((0,'x'),1),((0,'y'),3),((1,'y'),3),((1,'z'),3),((2,'x'),2),((2,'y'),2)]
-
map
В конце цепочки координаты объединяются в кортеж:[((0,1),'x'),((0,3),'y'),((1,3),'y'),((1,3),'z'),((2,2),'x'),((2,2),'y')]
-
groupBy
Группы по координатам:[[((0,1),'x')],[((0,3),'y')],[((1,3),'y'),((1,3),'z')],[((2,2),'x'),((2,2),'y')]]
-
Первый
map
объединяет символы с той же координатой в строки с этой координатой.
Комментарии:
1.
map ( s@(((x,y),_):_) -> (x, y, map snd s))
тоже должно выполнить эту работу.2. (главное, что меня раздражало, это нули
(0,0,[])
. во всяком случае,undefined
следовало использовать s . но, конечно, как написано, этот fold просто повторно реализуетmap
.)3. @WillNess: Спасибо за отзыв. Вы правы
(0,0,[])
, это некрасиво. Ваше предложение использоватьmap snd
etc. намного лучше. Я обновил соответствующим образом.4. … и теперь он может работать с любым
Eq
типом, а не толькоInt
с or(Num,Eq)
. 🙂5. @WillNess: Спасибо, я тоже это сделал. 🙂