gpt4 book ai didi

list - 在 Scala 中是否有一种安全的方法来转置不等长列表的列表?

转载 作者:行者123 更新时间:2023-12-04 01:55:35 26 4
gpt4 key购买 nike

鉴于以下列表:

val l = List(List(1, 2, 3), List(4, 5), List(6, 7, 8))

如果我尝试转置它,Scala 会抛出以下错误:
scala> List.transpose(l)
java.util.NoSuchElementException: head of empty list
at scala.Nil$.head(List.scala:1365)
at scala.Nil$.head(List.scala:1362)
at scala.List$$anonfun$transpose$1.apply(List.scala:417)
at scala.List$$anonfun$transpose$1.apply(List.scala:417)
at scala.List.map(List.scala:812)
at scala.List$.transpose(List.scala:417)
at .<init>(<console>:6)
at .<clinit>(<console>)
at RequestResult...

这是因为 List.transpose假设等长列表,因此使用 head方法:
def transpose[A](xss: List[List[A]]): List[List[A]] = {
val buf = new ListBuffer[List[A]]
var yss = xss
while (!yss.head.isEmpty) {
buf += (yss map (_.head))
yss = (yss map (_.tail))
}
buf.toList
}

我想得到以下内容:
List(List(1, 4, 6), List(2, 5, 7), List(3, 8))

正在编写我自己的版本 transpose最好的方法来做到这一点?这就是我想出的:
def myTranspose[A](xss: List[List[A]]): List[List[A]] = {
val buf = new ListBuffer[List[A]]
var yss = xss
while (!yss.head.isEmpty) {
buf += (yss filter (!_.isEmpty) map (_.head))
yss = (yss filter (!_.isEmpty) map (_.tail))
}
buf.toList
}

更新:我有兴趣比较这里提供的不同解决方案的速度,所以我整理了以下小基准:
import scala.testing.Benchmark
import scala.collection.mutable.ListBuffer

trait Transpose extends Benchmark {
def transpose[Int](xss: List[List[Int]]): List[List[Int]] = Nil
val list: List[List[Int]] = List(List(1,2,3), Nil, List(4,5,99,100), List(6,7,8))
def run = {
val l = transpose(list)
println(l)
l
}
}

object PRTranspose extends Transpose {
override def transpose[Int](xss: List[List[Int]]): List[List[Int]] = {
val buf = new ListBuffer[List[Int]]
var yss = xss
while (!yss.head.isEmpty) {
buf += (yss filter (!_.isEmpty) map (_.head))
yss = (yss filter (!_.isEmpty) map (_.tail))
}
buf.toList
}
}

object ACTranspose extends Transpose {
override def transpose[Int](xss: List[List[Int]]): List[List[Int]] = {
val b = new ListBuffer[List[Int]]
var y = xss filter (!_.isEmpty)
while (!y.isEmpty) {
b += y map (_.head)
y = y map (_.tail) filter (!_.isEmpty)
}
b.toList
}
}

object ETranspose extends Transpose {
override def transpose[Int](xss: List[List[Int]]): List[List[Int]] = xss.filter(!_.isEmpty) match {
case Nil => Nil
case ys: List[List[Int]] => ys.map{ _.head }::transpose(ys.map{ _.tail })
}
}

我的命令是:
scala PFTranspose 5 out.log
scala ACTranspose 5 out.log
scala ETranspose 5 out.log

我的结果是:
PRTranspose$            10              0               1               1               0
ACTranspose$ 9 2 0 0 0
ETranspose$ 9 3 2 3 1

最佳答案

这个怎么样:

    scala> def transpose[A](xs: List[List[A]]): List[List[A]] = xs.filter(_.nonEmpty) match {    
| case Nil => Nil
| case ys: List[List[A]] => ys.map{ _.head }::transpose(ys.map{ _.tail })
| }
warning: there were unchecked warnings; re-run with -unchecked for details
transpose: [A](xs: List[List[A]])List[List[A]]

scala> val ls = List(List(1, 2, 3), List(4, 5), List(6, 7, 8))
ls: List[List[Int]] = List(List(1, 2, 3), List(4, 5), List(6, 7, 8))

scala> transpose(ls)
res0: List[List[Int]] = List(List(1, 4, 6), List(2, 5, 7), List(3, 8))

scala> val xs = List(List(1,2,3), List(4,5,99,100), List(6,7,8))
xs: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 99, 100), List(6, 7, 8))

scala> transpose(xs)
res1: List[List[Int]] = List(List(1, 4, 6), List(2, 5, 7), List(3, 99, 8), List(100))

关于list - 在 Scala 中是否有一种安全的方法来转置不等长列表的列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1683312/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com