【问题标题】:Second argument replacing first scala第二个参数替换第一个 scala
【发布时间】:2017-12-04 00:16:44
【问题描述】:
我正在尝试在 scala ( ^ ) 中定义一个函数,它接受 2 个值并像
一样打印它们
2
x
这是我目前所拥有的......
class $ (val text2D: Array[Array[Char]])
{
def ^(that: $) =
{
" " ++ s"${this.text2D(0)(0)}" ++
"\n" ++ s"${that.text2D(0)(0)}"
}
def +(that: $) = this.text2D + "+" + that.text2D
override def toString = s"${this.text2D(0)(0)}"
}
object $ {
val array = Array.ofDim[Char](1,1)
def apply(x: String): $ = {
array (0)(0) = x.charAt(0)
new $ (array)
}
}
val x = $("x")
println(x)
val x2 = $("x") ^ $("2")
println(x2)
当我运行它时,我没有得到我期望的输出,而是得到了
2
2
为什么只取第二个元素?任何帮助将不胜感激。
【问题讨论】:
标签:
arrays
scala
function
multidimensional-array
【解决方案1】:
object 创建一个单例,因此您使用的(可变)数组在对apply 的调用之间共享。您需要在apply 调用中分配该数组内部。
def apply(x: String): $ = {
val array = Array.ofDim[Char](1,1)
array (0)(0) = x.charAt(0)
new $ (array)
}
另外,有点不相关,但我相信你的论点倒退了。要得到你想要的输出,你需要
" " ++ s"${that.text2D(0)(0)}" ++
"\n" ++ s"${this.text2D(0)(0)}"
【解决方案2】:
我认为你需要的是这样的:
class $(val text2D: Array[String]) {
def ^(that: $): $ = {
if (this.text2D.length == 0)
that
else if (that.text2D.length == 0)
this
else {
val thisW = this.text2D(0).length
val thatW = that.text2D(0).length
// cross-pad arrays to have the same width
val padThisRight = " " * thatW
val padThatLeft = " " * thisW
val thisPaddedW = this.text2D.map(_ + padThisRight)
val thatPaddedW = that.text2D.map(padThatLeft + _)
// first lines comes from that!
new $(thatPaddedW ++ thisPaddedW)
}
}
def +(that: $): $ = {
if (this.text2D.length == 0)
that
else if (that.text2D.length == 0)
this
else {
val thisH = this.text2D.length
val thatH = that.text2D.length
val thisW = this.text2D(0).length
val thatW = that.text2D(0).length
// pad arrays to have the same height
val emptyThis = " " * thisW
val emptyThat = " " * thatW
val thisPaddedH = if (thisH >= thatH) this.text2D else Array.fill(thatH - thisH)(emptyThis) ++ this.text2D
val thatPaddedH = if (thisH <= thatH) that.text2D else Array.fill(thisH - thatH)(emptyThat) ++ that.text2D
new $(thisPaddedH.zip(thatPaddedH).map(p => p._1 + p._2))
}
}
override def toString = text2D.mkString("\n")
}
object $ {
def apply(x: String): $ = {
new $(Array[String](x))
}
}
然后
val x2 = $("x") ^ $("2")
println(s"x2:\n$x2")
println("----------------------------")
val z = x2 + $(" + ") + y2
println(s"z:\n$z")
println("----------------------------")
val zz = x2 + $(" + ") + (y2 ^ $("3"))
println(s"zz:\n$zz")
println("----------------------------")
产生以下输出
x2:
2
x
----------------------------
z:
2 2
x + y
----------------------------
zz:
3
2 2
x + y
----------------------------
这里的主要思想是$ 上的操作会产生另一个$ 实例而不是String(我使用String 而不是Array[Char],因为它看起来更容易并且没有明显的缺点)。通过这种方式,您不必重新解析 String 将其拆分为新行,并且不必想知道如何处理字符串未正确对齐的情况。所以现在操作符^ 和+ 只是将两个二维数组对齐以具有相同的宽度或相同的高度,然后将它们连接起来的练习。