问题描述
我正在尝试学习 OCaml,因为我是这门语言的新手,我偶然发现了这个问题,在我需要合并 2 种这些列表的函数中,我似乎无法找到查看的方法,如果已经有一个带键的元素,如果有,如何连接后面的元素。希望得到任何指导。
例如,如果我有:
l1: [(k,[e]); (ka,[])]
l2: [(k,[f; g])]
我该如何结束:
fl: [(k,[e; f; g]); (ka,[])]
基本上,如何在组合元素的同时从两个列表中过滤键 k
。
解决方法
首先,使用列表作为映射是一个坏主意。最好使用专用的数据结构,例如映射和哈希表。
直接回答您的问题,您可以使用 (@)
运算符连接两个列表,例如,
# [1;2;3] @ [4;5;6];;
- : int list = [1; 2; 3; 4; 5; 6]
如果你在合并的时候不想要重复的元素,而且我觉得我重复自己的话,集合使用列表是不好的,最好使用专用的数据结构,例如集合和哈希集。但是如果你想继续,那么你可以通过在添加元素之前检查元素是否已经在列表中来合并两个列表而不会重复。易于实现但难以运行,从某种意义上说,以这种方式合并两个列表需要二次时间。
如果您仍然想坚持使用对列表,那么您会发现 List.assoc 函数很有用,因为它通过键查找值。整个算法将是,给定两个列表 xs
和 ys
,使用 ys
作为初始值 xs
折叠 acc
的元素,并且对于 (ky,y)
中的每个 ys
如果 ky
已经在 acc
中,找到与 ky
值 x
相关联的并删除 ({{1 }}) 它,然后合并 List.remove_assoc
和 x
并将合并的值添加到 y
列表中,否则(如果它不在 acc 中)只需添加 acc
acc` 。请注意,此算法不保留顺序,因此如果重要,您需要更复杂的东西。此外,如果您的键已排序,您可以使其更高效且更易于实现。
标准 OCaml 库中有一些函数用于处理对列表,其中每对的第一个元素是一个键。您会在此处找到它们的描述:https://ocaml.org/releases/4.12/api/List.html 在关联列表下。
我会重复@ivg 所说的话。如果您要使用的不仅仅是几双鞋,这不是您想要解决问题的方式。
,我猜你这样做是为了练习列表。 我要做的是将已经找到的密钥存储在累加器中
let mergePairs yourList =
let rec aux accKeys = function
| [] -> []
| x :: xs -> let k,v = x in if (* k in accKeys *) then aux accKeys xs (*we suppress already
existing keys*)
else (k,v @ (* get all the list of the other pairs with key = k in xs*))
:: aux (k::accKeys) xs
in aux [] yourList;;