F#使用自定义条件求列表交集的语法问题及解决方法
F# 按属性值匹配筛选列表元素问题解决
我有两个列表:第一个是结构化记录列表,每条记录包含Id属性,该Id是字符串包装类型;第二个是简单的字符串列表。需要筛选出第一个列表中所有Id存在于第二个列表中的记录。
在C#中实现该需求非常简单,代码如下:
var intersect = list1.Where(x => list2.Contains(x.Id.ToString()))
虽然存在更高效的交集计算方式,但C#搭配LINQ可以很便捷地得到所需结果。
我刚接触F#不久,尝试实现相同需求时遇到了问题,最初编写的代码如下:
list1 |> List.filter(fun x -> List.contains (x.Id.ToString() list2))
编译器报出类型不匹配错误:
This expression was expected to have type 'bool' but here has type ''a list -> bool'
解决方法
问题出在语法使用错误:List.contains 接收两个参数,第一个是要查找的元素,第二个是目标列表。之前的写法错误地将 list2 放到了和 x.Id.ToString() 同一对括号内,导致参数传递逻辑错误。
正确写法只需用括号单独包裹需要优先执行的 x.Id.ToString() 即可:
list1 |> List.filter(fun x -> List.contains (x.Id.ToString()) list2)
如果数据量较大,推荐先将第二个列表转为集合提升查询效率:
let idSet = set list2 list1 |> List.filter (fun x -> idSet.Contains (x.Id.ToString()))
内容的提问来源于stack exchange,提问作者Matt Austin
相关产品推荐
相关产品推荐

