首页 > 解决方案 > 对元组列表中的数量求和

问题描述

例如,如果我有一个这样的列表:

[("pizza", 4); ("milkshake", 2); ("chocolate", 2); ("pizza", 3); ("milkshake", 3); ("pizza", 4)]

我想总结元组的所有第二个元素,而第一个元组是相同的。我该怎么做?

输出应该是:

[("pizza", 11); ("milkshake", 5); ("chocolate, 2")]

标签: functional-programmingf#

解决方案


您可以使用List.groupBy根据项目名称对项目进行分组:

let items = [("pizza", 4); ("milkshake", 2); ("chocolate", 2); ("pizza", 3); ("milkshake", 3); ("pizza", 4)]
let grouped = List.groupBy fst items

// returns the following:
// [("pizza", [("pizza", 4); ("pizza", 3); ("pizza", 4)]);
//  ("milkshake", [("milkshake", 2); ("milkshake", 3)]);
//  ("chocolate", [("chocolate", 2)])]

这将返回一个元组列表,其中第一个条目是项目名称(例如比萨饼),第二个条目本身就是一个列表,包含与该名称匹配的所有原始元组。

然后您可以将每个子列表映射到第二个条目的总和:

let summed = List.map (fun (name, entries) -> (name, entries |> List.sumBy snd)) grouped

// returns [("pizza", 11); ("milkshake", 5); ("chocolate", 2)] as expected

List 模块的文档显示了用于处理列表的所有内置函数。

请注意,fstsnd是内置函数,它们分别返回双元素元组的第一个和第二个元素。

一旦您更熟悉 F#,您可能希望使用正向管道运算符|>更简洁地执行此操作:

let summed =
    items
    |> List.groupBy fst
    |> List.map (fun (name, entries) -> (name, entries |> List.sumBy snd))

推荐阅读