I have multidimensional arrays where the dimensions are saved in an ArrayBuffer
.
When I print it, obviously, I get e.g. ArrayBuffer(2, 2, 3)
, but I would like to have 2x2x3
. I know that I can do it as follows println(multiarray.dim.mkString("x"))
.
Is there any "magical" way that I get 2x2x3
by simply issuing println(multiarray.dim)
?
EDIT
dim
is method of the multidimensional arrays that gives the dimensions...
If dim
returns an ArrayBuffer, then, no, you can't just use println(multiarray.dim)
. Here are some simple alternatives though:
Define a method to return the dimensions as a String (in your multiarray class):
def dimStr = dim mkString "x"
Define a utility method for printing:
def printdim(buffer: ArrayBuffer[Int]) = println(buffer mkString "x")
// or
def printdim(multiarray: MultiArray) = println(multiarray.dim mkString "x")
Generalizing toString:
With a bit more effort, you can define a version of println
that will work the way you'd like. The idea is to abstract the String-creation logic. The power of this approach is that, once the basic infrastructure is in place, you're able to control the "stringification" of any type just by bringing an appropriate implicit into scope.
Start by defining a type class:
trait Stringable[T] extends (T => String)
Provide a default implementation of the type class (which just falls back on the ordinary toString
method):
class DefaultStringable[T] extends Stringable[T] {
def apply(x: T) = x.toString
}
object DefaultStringable {
implicit def any2stringable[T]: Stringable[T] = new DefaultStringable[T]
}
Implement the type class for your use case:
implicit object DimIsStringable extends Stringable[ArrayBuffer[Int]] {
def apply(buf: ArrayBuffer[Int]) = buf mkString "x"
}
Define a print method that uses the type class:
def myprintln[T](x: T)(implicit e: Stringable[T]) = e(x)
Fun.
import DefaultStringable._
myprintln(ArrayBuffer(1,2,3)) // prints "ArrayBuffer(1, 2, 3)"
Profit!
import DimIsStringable._
myprintln(ArrayBuffer(1,2,3)) // prints "1x2x3"
If desired, you can make the default type class always available without requiring any import. To do so, you provide the conversion in a companion module to the Stringable trait (as demonstrated below). The disadvantage of doing so is that you'll no longer have a compiler error to alert you if you forget to import an appropriate Stringable.
object Stringable {
implicit def any2stringable[T]: Stringable[T] = new DefaultStringable[T]
}
I m' not sure that would qualify as magical, but would that be ok?
class ArrayDim extends ArrayBufer[Int] {
override def toString = mkString ("x")
}
Edit :
Then in the code of your multidimensional array class,
replace dim = new ArrayBuffer
by dim = new ArrayDim
. Depending on how you fill the buffer, you may need minor changes in the code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With