我想知道按字母顺序排序元组中第一个字符串List[(String, String)]
的简单方法是什么,同时删除元组中第二个字符串的所有重复项。
感谢您的建议!
答案 0 :(得分:8)
我们可以进行性能测试吗?
val items = List("a" -> 0, "b" -> 1, "c" -> 0, "d" -> 0, "e" -> 1)
items.groupBy(_._2).toList
.sortBy(_._2.head._1)(new Ordering[String]() {
override def compare(x: String, y: String) = { -x.compareTo(y) }
})
.map(e => (e._2.head._1 -> e._1))
结果:
List((b,1), (a,0))
答案 1 :(得分:1)
对于好奇的人,评论中的答案仍然有效。
如果您已经有TreeMap,那么groupBy将构建TreeMaps。该行类似于idonnie的,除了不必再次排序。
TreeMap(data: _*) groupBy (_._2) map (p => (p._2.head._1, p._1))
我不确定为什么它不能从开箱即用的列表中构建一个TreeMap。我正在对抗感冒药。但是当人们发布这些问题时,它总是很有趣。
package object distinctby {
import scala.collection.IterableLike
import scala.collection.generic.CanBuildFrom
import scala.collection.mutable.{ Set => MutSet }
implicit class RichCollection[A, Repr](val xs: IterableLike[A, Repr]) extends AnyVal {
def distinctBy[B, That](f: A => B)(implicit cbf: CanBuildFrom[Repr, A, That]) = {
val builder = cbf(xs.repr)
val i = xs.iterator
val set = MutSet[B]()
while (i.hasNext) {
val o = i.next
val b = f(o)
if (!set(b)) {
set += b
builder += o
}
}
builder.result
}
}
}
package distinctby {
import scala.collection.generic.CanBuildFrom
import scala.collection.immutable.TreeMap
object Test extends App {
val data = List("eins"->"one","un"->"one","zwei"->"two","deux"->"two")
println(data)
println(data distinctBy (_._2))
println(TreeMap((data map (_.swap)): _*))
println(TreeMap((data.reverse map (_.swap)): _*))
// groupBy yields a TreeMap of TreeMap, so head is the lexly first
println(TreeMap(data: _*) groupBy (_._2) map (p => (p._2.head._1, p._1)))
locally {
class CBF[A,B](implicit ord: Ordering[A])
extends CanBuildFrom[List[(A, B)], (A,B), TreeMap[A,B]] {
def apply(from: List[(A,B)]) = TreeMap.newBuilder[A, B](ord)
def apply() = TreeMap.newBuilder[A, B]
}
implicit def cbf[A,B](implicit ord: Ordering[A]) = new CBF[A,B]
println(data.distinctBy[String, TreeMap[String, String]](_._2)(cbf[String, String]).toSeq)
}
}
}
List((eins,one), (un,one), (zwei,two), (deux,two))
List((eins,one), (zwei,two))
Map(one -> un, two -> deux)
Map(one -> eins, two -> zwei)
Map(eins -> one, deux -> two)
ArrayBuffer((eins,one), (zwei,two))
答案 2 :(得分:1)
我只想使用List的sorted
方法来执行元组的默认排序。您还可以使用groupBy
(也由idonnie指出)为每对中的第二项获取不同的值。这是一个小例子:
scala> val tuples = scala.util.Random.shuffle("abcd".permutations.map{_.splitAt(2)}.toList) // generate some test data
tuples: List[(String, String)] = List((cb,ad), (dc,ab), (ba,dc), (bd,ca), (cb,da), (ca,db), (cd,ba), (cd,ab), (db,ca), (ba,cd), (ac,db), (ac,bd), (ab,cd), (ad,cb), (ca,bd), (bd,ac), (ad,bc), (db,ac), (da,bc), (da,cb), (bc,da), (dc,ba), (ab,dc), (bc,ad))
scala> tuples.sorted.groupBy(_._2).values.map(_.head).toList.sorted
res0: List[(String, String)] = List((ab,cd), (ab,dc), (ac,bd), (ac,db), (ad,bc), (ad,cb), (bc,ad), (bc,da), (bd,ac), (bd,ca), (cd,ab), (cd,ba))
对我来说,你没有指定一种特定的方法来选择要保留的重复内容似乎有点奇怪...这应该保留第一个(按第一个字符串排序),这就是我的意思假设你想要。如果您不关心保留哪一个,那么您可以取消对sorted
的第一次调用。如果您将第一次调用sorted
更改为sortBy(_._1)
,这也可能会稍微提高效率,但我对您的具体应用程序知之甚少,以了解这是否会产生任何真正的差异。< / p>