我有一个函数,它接受一个整数列表列表,特别是Seq[Seq[Int]]
。然后我通过阅读文本文件并使用split
生成此数据,并生成Array
列表。 Scala不承认这一点,他提出了一个匹配错误。但是IndexedSeq
或Array
单独使用Seq[Int]
函数就可以了,显然只有嵌套集合才是问题。我如何隐式地将IndexedSeq[Array[Int]]
转换为Seq[Seq[Int]]
,或者除了使用toList
之外我还能如何做到这一点,如下所示?例如,Iterable[Iterable[Int]]
似乎很好,但我不能使用它。
scala> def g(x:Seq[Int]) = x.sum
g: (x: Seq[Int])Int
scala> g("1 2 3".split(" ").map(_.toInt))
res6: Int = 6
scala> def f(x:Seq[Seq[Int]]) = x.map(_.sum).sum
f: (x: Seq[Seq[Int]])Int
scala> f(List("1 2 3", "3 4 5").map(_.split(" ").map(_.toInt)))
<console>:9: error: type mismatch;
found : List[Array[Int]]
required: Seq[Seq[Int]]
f(List("1 2 3", "3 4 5").map(_.split(" ").map(_.toInt)))
^
scala> f(List("1 2 3", "3 4 5").map(_.split(" ").map(_.toInt).toList))
res8: Int = 18
答案 0 :(得分:2)
问题是Array
没有实现SeqLike
。通常,对ArrayOps
中定义的WrappedArray
或scala.predef
的隐式转换允许使用类似Seq
的数组。但是,在您的情况下,数组作为泛型参数从隐式转换中“隐藏”。一种解决方案是提示编译器,您可以将隐式转换应用于通用参数,如下所示:
def f[C <% Seq[Int]](x:Seq[C]) = x.map(_.sum).sum
这与保罗上面的回应类似。问题是在Scala 2.11中不推荐使用视图边界,并且使用已弃用的语言功能并不是一个好主意。幸运的是,视图边界可以重写为上下文边界,如下所示:
def f[C](x:Seq[C])(implicit conv: C => Seq[Int]) = x.map(_.sum).sum
现在,假设存在从C
到Seq[Int]
的隐式转换,它实际上存在于predef中。
答案 1 :(得分:1)
这个怎么样:
implicit def _convert(b:List[Array[Int]]):Seq[Seq[Int]]=b.map(_.toList)
答案 2 :(得分:1)
重新定义f更灵活。
由于Traversable是List,Seq,Array等的父级,因此如果它基于Traversable,则f将与这些容器兼容。 Traversable有sum,flatten和map,这就是所需要的。
这是多么棘手的是
stack install package_name
是挑剔的,并且不会对def f(y:Traversable[Traversable[Int]]):Int = y.flatten.sum
类型的y工作,尽管它适用于List[Array[Int]]
为了减少挑剔,一些类型的视图边界将起作用。
最初,我用flatten / sum操作替换了你的总和。
Array[List[Int]]
我发现这似乎也有效,但我没有进行太多测试:
def f[Y<%Traversable[K],K<%Traversable[Int]](y:Y):Int=y.flatten.sum
此def f[Y <% Traversable[K], K <% Traversable[Int]](y:Y):Int=y.map(_.sum).sum
语法将Y viewable表示为某些类型K的Traversable [K],可以作为Int的遍历进行查看。
定义一些不同的容器,包括您需要的容器:
<%
测试:
scala> val myListOfArray = List(Array(1,2,3),Array(3,4,5))
val myListOfArray = List(Array(1,2,3),Array(3,4,5))
myListOfArray: List[Array[Int]] = List(Array(1, 2, 3), Array(3, 4, 5))
scala> val myArrayOfList = Array(List(1,2,3),List(3,4,5))
val myArrayOfList = Array(List(1,2,3),List(3,4,5))
myArrayOfList: Array[List[Int]] = Array(List(1, 2, 3), List(3, 4, 5))
scala> val myListOfList = List(List(1,2,3),List(3,4,5))
val myListOfList = List(List(1,2,3),List(3,4,5))
myListOfList: List[List[Int]] = List(List(1, 2, 3), List(3, 4, 5))
scala> val myListOfRange = List(1 to 3, 3 to 5)
val myListOfRange = List(1 to 3, 3 to 5)
myListOfRange: List[scala.collection.immutable.Range.Inclusive] = List(Range(1, 2, 3), Range(3, 4, 5))