Scala新手求助:如何用数组过滤元组数组?
解决Scala元组数组过滤问题
你遇到的问题是filter里的语法错误——_.1这种写法不符合Scala的语法规则,因为下划线_在contains的参数位置时,代表的是整个传入的元组对象,不能直接通过.1来访问它的第一个元素。咱们来一步步修复这个问题:
原因分析
原代码arrayTuple.filter(numbers.contains(_.1))的问题在于:当你把_.1作为contains的参数时,Scala无法识别这个语法——_在这里是一个占位符,代表filter接收的每个元组元素,但你不能直接给它加属性访问符。正确的做法是先拿到元组,再提取它的第一个元素去做判断。
修复方案
这里有几种简洁且正确的写法,你可以根据自己的习惯选择:
1. 显式访问元组元素
直接在filter的匿名函数里定义参数,然后通过_1访问元组的第一个元素:
val numbers = Array(1, 2, 3, 4, 5) val arrayTuple = Array((1,2),(10,5),(40,5),(3,4)) // 显式参数写法 val filtered = arrayTuple.filter(t => numbers.contains(t._1))
2. 模式匹配解构元组(更易读)
用Scala的模式匹配来解构元组,直接提取第一个元素,代码可读性更高:
val filtered = arrayTuple.filter { case (firstNum, _) => numbers.contains(firstNum) }
这里case (firstNum, _)表示把每个元组的第一个元素绑定到firstNum,第二个元素用_忽略,然后判断firstNum是否在numbers数组中。
3. 优化性能(可选)
如果numbers数组比较大,建议把它转换成Set——因为数组的contains是O(n)时间复杂度,而Set的contains是O(1),性能会好很多:
val numberSet = numbers.toSet val filtered = arrayTuple.filter { case (firstNum, _) => numberSet.contains(firstNum) }
验证结果
运行上面的代码后,filtered的结果会是:
Array((1,2), (3,4))
完全符合你想要的过滤效果。
内容的提问来源于stack exchange,提问作者Rémy Ntshaykolo
相关产品推荐
相关产品推荐

