【问题标题】:Changing the form of a tuple改变元组的形式
【发布时间】:2018-09-26 00:57:11
【问题描述】:

我有一个包含元组的列表。我想将收到的列表的形式更改为不同的形式。下面的例子:

我正在接受 [[(String, Int, String, Int, String, Double)]][[(a,b,c,d,e,f)]]

我想把它变成如下形式的一个元组列表:

[(String,Double,Int)] 特别是[(e, ((d*f)/(d)), d)]

我正在尝试计算 GPA,其中列表包含一个元组列表,其中包含一个人正在学习的所有课程。 e 是人名,d 是学分数,f 是成绩点。每个元组中的名称都相同,但成绩和学分不同。

我不明白如何遍历列表列表中的所有元组并获取每个元组的df,这是我计算 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))

当我尝试在底部进行此计算时,它说中间元素不是双精度数。除了那个错误之外,这是在正确的方向吗?

谢谢

【问题讨论】:

  • 也许join 函数会有所帮助。它可以获取列表列表并将其“展平”为单个列表。
  • 我正在尝试你能展示你的尝试吗?
  • 第一步是编写一个转换单个元组的函数,即(String, Int, String, Int, String, Double) -> (String, Double, Int)类型的函数。你有没有尝试过这样做?告诉我们你已经走了多远!
  • 是的,我目前有:computeGpas = show 。 (map (map calcGPA) .groupBy groupName .sortBy byName) 。 (映射 stringToTuple) 。 (地图词)。行 calcGPA [[subject, num, section, credits, name,grade]] = (name,(grade*credits)/credits, credits) 这是我一直在尝试使用的。谢谢你。 @丹尼尔瓦格纳

标签: haskell tuples


【解决方案1】:

首先定义一个函数来计算 GPA,例如: gpa (a,b,c,d,e,f) = (e,d*f/d,d)

您需要两次映射列表,第一次用于外部列表,第二次用于内部列表,例如: fmap (fmap gpa) listOfLists

或使用&lt;$&gt; 运算符: ((<$>) gpa) <$> listOfLists

另一个名为protolude 的前奏也定义了一个执行此操作的运算符,看起来非常直观: gpa <<$>> listOfLists

【讨论】:

    【解决方案2】:

    根据您的评论,不确定这是否正是您想要的,但它可能会有所帮助:

    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 first concats 元组列表列表,基本上是[[a]]-&gt;[a]。然后在concated 列表上使用maps morphTuple 函数。所以每个元素都从元组(String,Int,String,Int,String,Double) 变形为(String,Double,Int)morphTuple 函数使用fromIntegralInt 转换为Double,然后相应地进行乘除。当然还有更简洁的解决方案,例如 convertTupleList 尖叫无点风格,但我将把它作为优化和纠正任何规范错误的练习。我还建议剖析 GHCi 中的 concatmap 函数。更多参考资料和有用的列表功能:Haskell Report Folds

    PS:请添加编码尝试并使用编辑按钮更新原始问题。

    【讨论】:

    • 谢谢!这是有道理的,并成功地将列表转换为我正在寻找的形式。我仍然在数学和计算代码中的 GPA 方面遇到问题。我用我尝试过的内容更新了上面的帖子。谢谢
    • @Riley 使用fromIntegralInt 转换为Double。所以在你的更新中cfInts 需要Double。 Haskell 不会隐式转换类型。正如我在解释中简要指出的那样,您需要这样做:(b*(fromIntegral c)+e*(fromIntegral f))/(b+e)be 已经是 Double 类型,因此不需要转换。你正朝着正确的方向前进。我发布的参考资料在 groupBymap 等列表中有许多有用的函数,在 GHCi 中使用它们来解决错误并逐步构建更复杂的函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多