簡體   English   中英

如何根據類別進行折疊執行多次折疊

[英]How to make fold perform multiple folds based on a category

我可以將哪個運算符傳遞給其中一個折疊變量,這些變量允許我在元組列表中將按元組項1分組的元組2進行求和?

所以,假設我有這個清單:

[ ('A', 1) , ('A', 3) , ('B', 4 ) , ('C', 10) , ('C', 1) ]

我想制作清單:

[ ('A', 4) , ('B', 4) , ('C', 11) ]

你可以看到它是一個Haskell化的表,因此這里表的實際表示並不重要; 這是獲取輸入數據並生成我感興趣的輸出的方法。我是Haskell的新手,並且具有C / C ++ / C#的背景知識。 我已經做了足夠的教程來識別折疊的應用,但是無法弄清楚看起來需要的子折疊。

編輯:如果這有助於其他任何人,這里是我使用group,foldl1和map的解決方案,靈感來自ingo的回復:

import qualified Data.List as List

mygroup :: [ (Char,Int) ] -> [ [(Char,Int)] ]
mygroup = List.groupBy (\x y -> fst x == fst y) 

myfold :: [(Char,Int)] -> (Char,Int)
myfold = foldl1 (\x y -> (fst x, snd x + snd y))

mysum :: [(Char,Int)] -> [(Char,Int)]
mysum = map myfold . mygroup

運行時:

*ListSum> mysum [ ('A',1) , ('A',2) , ('B',3) , ('C',4) , ('C',5) ]
[('A',3),('B',3),('C',9)]

mygroup通過提供等價運算符來演示如何創建組。 它說如果他們的第一個元組項目是相同的,那么兩個成員屬於同一組。

myfold展示了如何將兩個元組相加。 它使用列表中的第一個元組作為折疊的初始狀態,並從每個元組的第二個項的總和中組成結果元組。

mysum使用map組成這兩個函數。

我可能會花更多的時間在這上面看看我是否可以打破對數據模式的依賴,這是當前[(Char,Int)] 我認為這意味着提供groupBy運算符和fold運算符,並且可能只是組成groupBy,foldl1和map的練習。 我是新來的。

我是否獲得無點積分? :)

你想要的是關於用特定標准對項目進行分組然后折疊組。

實現示例的最簡單方法是使用Data.Map的關聯映射對項進行分組。

import qualified Data.Map as Map

sumGroups :: [(Char, Int)] -> [(Char, Int)]
sumGroups = Map.assocs . Map.fromListWith (+)

這使用fromListWith函數來組合具有相同鍵的項,並將生成的映射轉換回具有assocs的列表。

*Main> sumGroups [ ('A', 1) , ('A', 3) , ('B', 4 ) , ('C', 10) , ('C', 1) ]
[('A',4),('B',4),('C',11)]

毫無意義的樂趣:

import Data.List
import Data.Function
import Control.Arrow

sumGroups = map (fst . head &&& sum . map snd) . groupBy ((==) `on` fst) 

從概念上講,您需要兩個步驟:

transform [('A', 1) , ('A', 3) , ('B', 4 ) , ('C', 10) , ('C', 1)]
to [('A', [1,3,4]), ('C', [10, 1])]
and further to [('A', 8), ('C', 11)]

可以幫助您的功能:groupBy,using,fst,map,sum

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM