Haskell中如何对嵌套元组列表的特定值按行求和?
在Haskell中计算嵌套元组列表的元素求和值
我有一个嵌套元组列表,每个元组格式为(a, b, c, d),其中c是a对应的值,d是b对应的值,具体列表如下:
[ [("A","B",0,3),("A","C",0,3),("B","C",0,3)], [("A","B",0,3),("A","C",0,3),("B","C",1,1)], [("A","B",0,3),("A","C",0,3),("B","C",3,0)], [("A","B",0,3),("A","C",1,1),("B","C",0,3)], [("A","B",0,3),("A","C",1,1),("B","C",1,1)], [("A","B",0,3),("A","C",1,1),("B","C",3,0)], [("A","B",0,3),("A","C",3,0),("B","C",0,3)], [("A","B",0,3),("A","C",3,0),("B","C",1,1)], [("A","B",0,3),("A","C",3,0),("B","C",3,0)], [("A","B",1,1),("A","C",0,3),("B","C",0,3)], [("A","B",1,1),("A","C",0,3),("B","C",1,1)], [("A","B",1,1),("A","C",0,3),("B","C",3,0)], [("A","B",1,1),("A","C",1,1),("B","C",0,3)], [("A","B",1,1),("A","C",1,1),("B","C",1,1)], [("A","B",1,1),("A","C",1,1),("B","C",3,0)], [("A","B",1,1),("A","C",3,0),("B","C",0,3)], [("A","B",1,1),("A","C",3,0),("B","C",1,1)], [("A","B",1,1),("A","C",3,0),("B","C",3,0)], [("A","B",3,0),("A","C",0,3),("B","C",0,3)], [("A","B",3,0),("A","C",0,3),("B","C",1,1)], [("A","B",3,0),("A","C",0,3),("B","C",3,0)], [("A","B",3,0),("A","C",1,1),("B","C",0,3)], [("A","B",3,0),("A","C",1,1),("B","C",1,1)], [("A","B",3,0),("A","C",1,1),("B","C",3,0)], [("A","B",3,0),("A","C",3,0),("B","C",0,3)], [("A","B",3,0),("A","C",3,0),("B","C",1,1)], [("A","B",3,0),("A","C",3,0),("B","C",3,0)] ]
需要对每一行中的A、B、C对应的值分别求和:
- 示例1:处理列表
[("A","B",3,0),("A","C",1,1),("B","C",3,0)],结果为A=>4,B=>3,C=>1 - 示例2:处理列表
[("A","B",3,0),("A","C",3,0),("B","C",3,0)],结果为A=>6,B=>3,C=>0
实现方案
方法1:使用Map实现通用求和
这种方法适用于元素不限于A、B、C的场景,通过Data.Map动态累加每个元素的总和:
import Data.Map (Map) import qualified Data.Map as Map -- 处理单个行的求和逻辑 sumRow :: [(String, String, Int, Int)] -> Map String Int sumRow = foldl updateSum Map.empty where updateSum acc (elemX, elemY, valX, valY) = Map.insertWith (+) elemX valX $ Map.insertWith (+) elemY valY acc -- 处理整个嵌套列表 sumAllRows :: [[(String, String, Int, Int)]] -> [Map String Int] sumAllRows = map sumRow
测试示例:
testRow1 = [("A","B",3,0),("A","C",1,1),("B","C",3,0)] -- sumRow testRow1 → fromList [("A",4),("B",3),("C",1)] testRow2 = [("A","B",3,0),("A","C",3,0),("B","C",3,0)] -- sumRow testRow2 → fromList [("A",6),("B",3),("C",0)]
方法2:针对A、B、C的专用求和
如果确定只有A、B、C三个元素,用三元组直接累加会更高效,不需要依赖Map:
-- 单个行求和,返回(A总和, B总和, C总和) sumRow' :: [(String, String, Int, Int)] -> (Int, Int, Int) sumRow' = foldl update (0, 0, 0) where update (aSum, bSum, cSum) (x, y, valX, valY) = case (x, y) of ("A", "B") -> (aSum + valX, bSum + valY, cSum) ("A", "C") -> (aSum + valX, bSum, cSum + valY) ("B", "C") -> (aSum, bSum + valX, cSum + valY) -- 若有其他元素组合,可在此扩展分支
测试示例:
-- sumRow' testRow1 → (4, 3, 1) -- sumRow' testRow2 → (6, 3, 0)
内容的提问来源于stack exchange,提问作者Devrim Altınkurt
相关产品推荐
相关产品推荐

