【问题标题】:a clean way to combine two tuples into a new larger tuple in scala?在scala中将两个元组组合成一个新的更大元组的干净方法?
【发布时间】:2012-01-27 03:00:32
【问题描述】:

假设我有以下元组:

scala> val t1 = Tuple2("abcd", "efg")
t1: (java.lang.String, java.lang.String) = (abcd,efg)

scala> val t2 = Tuple2(1234, "lmnop")
t2: (Int, java.lang.String) = (1234,lmnop)

scala> val t3 = Tuple3("qrs", "tuv", "wxyz")
t3: (java.lang.String, java.lang.String, java.lang.String) = (qrs,tuv,wxyz)

有没有一种友好的方法可以将它们(如果需要,分两步)组合成一个 Tuple7?我真的在寻找组合任意大小的元组的一般答案,并意识到由于最大元组大小的上限而存在限制。我专门寻找元组结果,而不是集合。

【问题讨论】:

标签: scala scalaz


【解决方案1】:

Shapeless 需要依赖方法类型 (-Ydependent-method-types),我希望 2.9.1 有一个可下载的二进制文件,这样我就可以简单地试用它,但它看起来真的很优雅。基于this unit test,它将适用于您的情况,如下所示:

import shapeless.Tuples._
import shapeless.HList._
val t7 = (t1.hlisted ::: t2.hlisted ::: t3.hlisted).tupled

虽然 Miles 表示不保证支持,但它实际上有单元测试,并且源代码在 github 上,具有开源许可证,因此至少它不仅仅是博客文章中的实验。

编辑:作为广告工作 - 编译需要一些时间,我必须将 -Xss1m 添加到 sbt:

$ scala -Ydependent-method-types -cp target/scala-2.9.1/shapeless_2.9.1-1.1.0.jar
Welcome to Scala version 2.9.1.final (Java HotSpot(TM) Client VM, Java 1.7.0).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import shapeless.Tuples._
import shapeless.Tuples._

scala> import shapeless.HList._
import shapeless.HList._

scala> val t1 = Tuple2("abcd", "efg")
t1: (java.lang.String, java.lang.String) = (abcd,efg)

scala> val t2 = Tuple2(1234, "lmnop")
t2: (Int, java.lang.String) = (1234,lmnop)

scala> val t3 = Tuple3("qrs", "tuv", "wxyz")
t3: (java.lang.String, java.lang.String, java.lang.String) = (qrs,tuv,wxyz)

scala> (t1.hlisted ::: t2.hlisted ::: t3.hlisted).tupled
res0: (java.lang.String, java.lang.String, Int, java.lang.String, java.lang.String,
java.lang.String, java.lang.String) = (abcd,efg,1234,lmnop,qrs,tuv,wxyz)

【讨论】:

  • 在某些时候,我可能会将HList 样式的操作直接添加到元组上,这样您就可以跳过hlisted/tupled shuffle,只需编写t1 ::: t2 ::: t3。我已经在topic/tuples branch 上通过了,但在我承诺之前,我想确保额外的隐式不会造成破坏。
  • 是的,这正是我想要的。感谢 huynhjl 指出它并证明它可以满足问题,并感谢 Miles 编写了如此酷的包!
  • 单元测试的链接不再存在。这是什么版本的无形?我在 scala 2.11 的版本上找不到 import shapeless.Tuples._
【解决方案2】:

你真的需要在这里使用集合,特别是如果所有元素都是相同的类型。你可以毫不费力地将元组组合成一个List

def combine(xss: Product*) = xss.toList.flatten(_.productIterator)

用你的例子:

scala> combine(t1, t2, t3)
res1: List[Any] = List(abcd, efg, hijk, lmnop, qrs, tuv, wxyz)

尝试将其转回元组是行不通的,因为您的转换方法(例如使用模式匹配)将无法返回特定的元组类型(该方法的返回类型是什么?),并且每个元素的类型信息已丢失。

【讨论】:

  • 我应该举一个更好的例子。不能保证元组的所有成员都属于同一类型,我正在专门寻找一种获取新元组的方法。在其他情况下,我会使用集合,但在这种情况下,答案需要一个元组。我已经提炼了这个问题...
猜你喜欢
  • 1970-01-01
  • 2015-10-30
  • 2022-01-11
  • 2021-08-02
  • 2022-06-15
  • 2018-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多