斯卡拉。如何创建接受具有不同参数的元组的通用方法?
Scala. How to create general method that accept tuple with different arities?
在我的应用程序中,我有很多地方需要获取元组列表,按元组的第一个元素对其进行分组,然后将其从其余元素中删除。例如,我有元组
(1, "Joe", "Account"), (1, "Tom", "Employer"), (2, "John", "Account"), and result should be Map(1 -> List(("Joe", "Account"), ("Joe", "Account")), 2 -> List(("John", "Account")))
很容易实现
data.groupBy(_._1).map { case (k, v) => k -> v.map(f => (f._2, f._3)) }
但我正在寻找通用解决方案,因为我可以有不同元数的元组,2、3、4 甚至 7。
我认为 Shapeless 或 Scalaz 可以帮助我,但我在这些库中的经验不足,请指出一些例子
这很容易使用 shapeless
实现(为简单起见,我不会将其推广到所有集合类型)。有特定类型 class 的元组可以将它们解构为头和尾称为 IsComposite
import shapeless.ops.tuple.IsComposite
def groupTail[P, H, T](tuples: List[P])(
implicit ic: IsComposite.Aux[P, H, T]): Map[H, List[T]] = {
tuples
.groupBy(ic.head)
.map { case (k, vs) => (k, vs.map(ic.tail)) }
}
这适用于您的情况:
val data =
List((1, "Joe", "Account"), (1, "Tom", "Employer"), (2, "John", "Account"))
assert {
groupTail(data) == Map(
1 -> List(("Joe", "Account"), ("Tom", "Employer")),
2 -> List(("John", "Account"))
)
}
以及 Tuple4
不同类型:
val data2 = List((1, 1, "a", 'a), (1, 2, "b", 'b), (2, 1, "a", 'b))
assert {
groupTail(data2) == Map(
1 -> List((1, "a", 'a), (2, "b", 'b)),
2 -> List((1, "a", 'b))
)
}
可运行代码可用at Scastie
在我的应用程序中,我有很多地方需要获取元组列表,按元组的第一个元素对其进行分组,然后将其从其余元素中删除。例如,我有元组
(1, "Joe", "Account"), (1, "Tom", "Employer"), (2, "John", "Account"), and result should be Map(1 -> List(("Joe", "Account"), ("Joe", "Account")), 2 -> List(("John", "Account")))
很容易实现
data.groupBy(_._1).map { case (k, v) => k -> v.map(f => (f._2, f._3)) }
但我正在寻找通用解决方案,因为我可以有不同元数的元组,2、3、4 甚至 7。 我认为 Shapeless 或 Scalaz 可以帮助我,但我在这些库中的经验不足,请指出一些例子
这很容易使用 shapeless
实现(为简单起见,我不会将其推广到所有集合类型)。有特定类型 class 的元组可以将它们解构为头和尾称为 IsComposite
import shapeless.ops.tuple.IsComposite
def groupTail[P, H, T](tuples: List[P])(
implicit ic: IsComposite.Aux[P, H, T]): Map[H, List[T]] = {
tuples
.groupBy(ic.head)
.map { case (k, vs) => (k, vs.map(ic.tail)) }
}
这适用于您的情况:
val data =
List((1, "Joe", "Account"), (1, "Tom", "Employer"), (2, "John", "Account"))
assert {
groupTail(data) == Map(
1 -> List(("Joe", "Account"), ("Tom", "Employer")),
2 -> List(("John", "Account"))
)
}
以及 Tuple4
不同类型:
val data2 = List((1, 1, "a", 'a), (1, 2, "b", 'b), (2, 1, "a", 'b))
assert {
groupTail(data2) == Map(
1 -> List((1, "a", 'a), (2, "b", 'b)),
2 -> List((1, "a", 'b))
)
}
可运行代码可用at Scastie