Gre*_*Cat 25 scala initialization multidimensional-array
通过放置类似的内容,可以很容易地在Java中初始化2D数组(或者实际上是任何多维数组):
int[][] x = new int[][] {
{ 3, 5, 7, },
{ 0, 4, 9, },
{ 1, 8, 6, },
};
Run Code Online (Sandbox Code Playgroud)
它易于阅读,类似于2D矩阵等.
但是我如何在Scala中做到这一点?
最好的我可以想出看起来,更简洁:
val x = Array(
Array(3, 5, 7),
Array(0, 4, 9),
Array(1, 8, 6)
)
Run Code Online (Sandbox Code Playgroud)
我在这里看到的问题:
Array),在每个Array调用中省略尾随如果我搞砸了,除了插入一些Array()在阵列的中间,它会好与编译器,但类型x将变得悄无声息Array[Any],而不是Array[Array[Int]]:
val x = Array(
Array(3, 5, 7),
Array(0, 4), 9, // <= OK with compiler, silently ruins x
Array(1, 8, 6)
)
Run Code Online (Sandbox Code Playgroud)
有一个防范它,直接指定类型,但它看起来比在Java中更难过:
val x: Array[Array[Int]] = Array(
Array(3, 5, 7),
Array(0, 4), 9, // <= this one would trigger a compiler error
Array(1, 8, 6)
)
Run Code Online (Sandbox Code Playgroud)
最后一个例子Array甚至需要比我int[][]在Java中说的多3倍.
这有什么明确的方法吗?
Lui*_*hys 16
就个人而言,为了清楚起见,我会把它吸干并输入(或剪切和粘贴)"Array"几次.当然,包括安全类型注释.但是,如果你真的没电子墨水,快速简单的黑客就是提供别名Array,例如:
val > = Array
val x: Array[Array[Int]] = >(
>(3, 5, 7),
>(0, 4, 9),
>(1, 8, 6)
)
Run Code Online (Sandbox Code Playgroud)
Array如果要缩短注释,还可以提供类型别名:
type >[T] = Array[T]
val x: >[>[Int]] = ...
Run Code Online (Sandbox Code Playgroud)
kir*_*uku 13
我建议使用Scala 2.10和宏:
object MatrixMacro {
import language.experimental.macros
import scala.reflect.macros.Context
import scala.util.Try
implicit class MatrixContext(sc: StringContext) {
def matrix(): Array[Array[Int]] = macro matrixImpl
}
def matrixImpl(c: Context)(): c.Expr[Array[Array[Int]]] = {
import c.universe.{ Try => _, _ }
val matrix = Try {
c.prefix.tree match {
case Apply(_, List(Apply(_, List(Literal(Constant(raw: String)))))) =>
def toArrayAST(c: List[TermTree]) =
Apply(Select(Select(Ident("scala"), newTermName("Array")), newTermName("apply")), c)
val matrix = raw split "\n" map (_.trim) filter (_.nonEmpty) map {
_ split "," map (_.trim.toInt)
}
if (matrix.map(_.length).distinct.size != 1)
c.abort(c.enclosingPosition, "rows of matrix do not have the same length")
val matrixAST = matrix map (_ map (i => Literal(Constant(i)))) map (i => toArrayAST(i.toList))
toArrayAST(matrixAST.toList)
}
}
c.Expr(matrix getOrElse c.abort(c.enclosingPosition, "not a matrix of Int"))
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
scala> import MatrixMacro._
import MatrixMacro._
scala> matrix"1"
res86: Array[Array[Int]] = Array(Array(1))
scala> matrix"1,2,3"
res87: Array[Array[Int]] = Array(Array(1, 2, 3))
scala> matrix"""
| 1, 2, 3
| 4, 5, 6
| 7, 8, 9
| """
res88: Array[Array[Int]] = Array(Array(1, 2, 3), Array(4, 5, 6), Array(7, 8, 9))
scala> matrix"""
| 1, 2
| 1
| """
<console>:57: error: rows of matrix do not have the same length
matrix"""
^
scala> matrix"a"
<console>:57: error: not a matrix of Int
matrix"a"
^
Run Code Online (Sandbox Code Playgroud)
我认为你不会缩短它.;)
如果仅使用Listof List(它本身不能保证每个子列表的大小相同)对您来说不是问题,并且您只关心简单的语法并避免创建时的错误,那么 scala 有多种方法可以创建很好的语法结构。
其中一种可能性是一个简单的助手:
object Matrix {
def apply[X]( elements: Tuple3[X, X, X]* ): List[List[X]] = {
elements.toList.map(_.productIterator.toList.asInstanceOf[List[X]] )
}
// Here you might add other overloads for Tuple4, Tuple5 etc if you need "matrixes" of those sizes
}
val x = Matrix(
(3, 5, 7),
(0, 4, 9),
(1, 8, 6)
)
Run Code Online (Sandbox Code Playgroud)
关于您的疑虑:
它一遍又一遍地重复“List”(就像除了 List 之外还可能有其他东西一样)
这里的情况并非如此。
它需要在每个 List 调用中省略尾随 ,
不幸的是,这仍然是正确的,考虑到 scala 的语法规则,你无能为力。
如果我搞砸了并在数组中间插入除 List() 之外的其他内容,编译器会正常工作,但 x 的类型会默默地变成 List[Any] 而不是 List[List[Int]]:
val x = List(
List(3, 5, 7),
List(0, 4), 9, // <= OK with compiler, silently ruins x
List(1, 8, 6)
)
Run Code Online (Sandbox Code Playgroud)
等效代码现在无法编译:
scala> val x = Matrix(
| (3, 5, 7),
| (0, 4), 9,
| (1, 8, 6)
| )
<console>:10: error: type mismatch;
found : (Int, Int)
required: (?, ?, ?)
(0, 4), 9,
Run Code Online (Sandbox Code Playgroud)
最后,如果您想显式指定元素的类型(假设您想防止无意中混合Ints 和Doubles 的可能性),您只需指定Matrix[Int]而不是丑陋的List[List[Int]]:
val x = Matrix[Int](
(3, 5, 7),
(0, 4, 9),
(1, 8, 6)
)
Run Code Online (Sandbox Code Playgroud)
编辑:我看到你在问题中List替换了。Array要使用数组,您只需在上面的代码中替换ListwithArray和toListwith即可。toArray
| 归档时间: |
|
| 查看次数: |
15027 次 |
| 最近记录: |