如何在具有两个元素的Set[(String,String)]Set[Tuple]上添加过滤器



我是scala的新手。我正在尝试对Set[(String,String(]应用筛选器。过滤器用于删除重复项,即使它区分大小写。

Input: Tuple 1 ("Low", "Low")
Tuple 2 ("medium", "medium")
Tuple 3 ("High", "High")
Tuple 4 ("Medium", "Medium")
Tuple 5 ("low", "low")
Output: Tuple 1 ("Low", "Low")
Tuple 2 ("High", "High")
Tuple 3 ("medium", "medium")

所以,如果字符串是Low和Low,那么过滤器应该给出Low(或先到的(,我尝试应用groupBy。那么,如何才能做到这一点呢?

Scala 2.13.x中提供的一个方便的工具是distinctBy()。不幸的是,它在Set上不可用,我想是因为集合在定义上是不同的。

input.toList
.distinctBy{case (a,b) => (a.toUpperCase,b.toUpperCase)}
.toSet
//res0: Set[(String, String)] = Set((Medium,Medium), (High,High), (low,low))

注意,根据定义,Set没有次序,所以";以先到者为准";实际上毫无意义。


2.13.x之前

如果你愿意采用标准的演示格式,那么你可以这样做。

input.map{case (a,b) => (a.capitalize,b.capitalize)}
//res0: Set[(String, String)] = Set((Low,Low), (High,High), (Medium,Medium))
val setOfPairs: Set[(String, String)] =
Set(("Low", "Low"), ("medium", "medium"), ("High", "High"), ("Medium", "Medium"), ("low", "low"))
setOfPairs.foldLeft(Set.empty[(String, String)]) { (acc, pair) =>
if (acc
.map { case (left, right) => (left.capitalize, right.capitalize) }
.contains((pair._1.capitalize, pair._2.capitalize))) acc
else acc + pair
}

这应该会给你先来的那一套。

如果您不使用scala 2.13.x,您可以按如下方式执行:

你可以使用这种不那么有效的方法(没有一致的(

Set(
"Low" -> "Low",
"medium" -> "medium",
"High" -> "High",
"low" -> "low")
.map { case tuple @ (key,value) => key.toUpperCase -> tuple }
.toMap
.values
.toSet

输出:Set((low,low), (medium,medium), (High,High))

或者:

Set(
"Low" -> "Low",
"medium" -> "medium",
"High" -> "High",
"low" -> "low")
.foldLeft((Seq.empty[String], Set.empty[(String,String)])) { case (seed @ (keys, set), tuple @ (key, _)) => {
val currKey = key.toUpperCase
if (keys.contains(currKey)) seed else (currKey +: keys, set + tuple)
}
}._2

输出:Set((Low,Low), (medium,medium), (High,High))

注意:为了提高效率,您可以使用而不是Set.empty,这是一种不检查重复的可迭代集合,然后在中_2将其转换为设置

List(
"Low" -> "Low",
"medium" -> "medium",
"High" -> "High",
"low" -> "low",
"high" -> "high")
.foldLeft((Seq.empty[String], Seq.empty[(String,String)])) { case (seed @ (keys, seq), tuple @ (key, _)) => {
val currKey = key.toUpperCase
if (keys.contains(currKey)) seed else (currKey +: keys, tuple +: seq)
}
}._2.toSet

(一致(

相关内容