我有一个包含元组的列表列表。我想将接收到的列表的形式更改为其他形式。下面的示例:
我正在接受
[[(String, Int, String, Int, String, Double)]]
或[[(a,b,c,d,e,f)]]
我想将其转换为以下形式的元组列表:
[(String,Double,Int)]
,特别是[(e, ((d*f)/(d)), d)]
我正在尝试计算GPA,其中该列表包含一个元组列表,其中包含一个人正在学习的所有课程。 e
是人物的名字,d
是学分的数量,f
是成绩。每个元组中的名称都相同,但是成绩和学分数量却不同。
我不明白如何遍历列表列表中的所有元组,并取每个元组的d
和f
作为计算GPA所需的值。
如果可以提供任何帮助将我推向正确的方向,将不胜感激。
谢谢
更新
现在我只有一个元组列表。看起来像这样:
[("Erikson,Ann",2.0,3),("Erikson,Ann",3.33,3),("Lewis,Buck",2.66,1),
("Lewis,Buck",2.0,3),("Smith,John",0.0,1),("Smith,John",1.66,3),
("Smith,John",1.33,3),("Torvell,Sarah",4.0,3)]
我需要为每个人创建一个元组。元组应具有以下形式: (名称,计算的GPA,总学分)
计算得出的gpa是每个元组的第二个元素乘以每个元组中的第三个元素,再加上相同操作与其他所有共享相同名称的元组的乘积。然后将该数字除以学分的总和(第三个元素)。具有相同名称的元组中所有第三个元素的总和是第三个元素。令人困惑和努力工作。最后,我希望每个人一个元组。
我正在尝试:
type MyType2 = (String, Double, Int)
groupNameTuple :: MyType2 -> MyType2 -> Bool
groupNameTuple (a,_,_) (b,_,_) = a==b
calcGPA :: MyType2 -> MyType2 -> MyType2
calcGPA (a,b,c) (d,e,f) = (a, ((b*c)+(e*f))/(b+e), (b+e))
当我尝试在底部进行此计算时,它说中间元素不是双精度。除了那个错误,这是正确的方向吗?
谢谢
答案 0 :(得分:0)
首先定义一个计算GPA的函数,例如:
gpa (a,b,c,d,e,f) = (e,d*f/d,d)
您将需要两次映射列表,第一次是外部列表,第二次是内部列表,例如:
fmap (fmap gpa) listOfLists
或使用<$>
运算符:
((<$>) gpa) <$> listOfLists
另一个称为protolude的前奏也定义了一个执行此操作的操作符,看起来很直观:
gpa <<$>> listOfLists
答案 1 :(得分:0)
不确定基于您的评论您到底想要的是什么,但这可能会有所帮助:
convertTupleList :: [[(String, Int, String, Int, String, Double)]] -> [(String,Double,Int)]
convertTupleList ts = map morphTuple $ concat ts
morphTuple :: (String, Int, String, Int, String, Double) -> (String, Double, Int)
morphTuple (_,_,_,d,e,f) = (e, (d'*f)/d', d)
where
d' = fromIntegral d
convertTupleList
首先是concat
元组列表的列表,基本上是[[a]]->[a]
。然后,它在map
列表上morphTuple
个concat
函数。因此,每个元素都从元组(String,Int,String,Int,String,Double)
变形为(String,Double,Int)
。 morphTuple
函数使用fromIntegral
将Int
转换为Double
,然后相乘和除法。当然,还有更清洁的解决方案,例如convertTupleList
尖叫无点样式,但我将其作为优化和纠正任何规范错误的练习。我还建议剖析GHCi中的concat
和map
函数。其他参考和有用的列表功能:Haskell Report Folds
PS:请添加编码尝试,并使用“编辑”按钮更新到原始问题。