打印集合:特定于变量

时间:2011-06-30 15:24:06

标签: scala

我有多维数组,其中维度保存在ArrayBuffer中。

当我打印它时,显然,我得到了ArrayBuffer(2, 2, 3),但我希望2x2x3。我知道我可以按照以下方式println(multiarray.dim.mkString("x"))进行操作。

通过简单发布2x2x3,我有println(multiarray.dim)的“神奇”方法吗?

修改

dim是多维数组的方法,它给出了维度......

4 个答案:

答案 0 :(得分:4)

如果dim返回一个ArrayBuffer,那么,不,你不能只使用println(multiarray.dim)。以下是一些简单的替代方案:

  1. 定义一个方法,将维度作为字符串返回(在多数组类中):

    def dimStr = dim mkString "x"
    
  2. 定义用于打印的实用程序方法:

    def printdim(buffer: ArrayBuffer[Int]) = println(buffer mkString "x")
    // or
    def printdim(multiarray: MultiArray) = println(multiarray.dim mkString "x")
    
  3. 概括到字符串:

    通过更多的努力,您可以定义一个可以按照您喜欢的方式工作的println版本。我们的想法是抽象String-creation逻辑。这种方法的强大之处在于,一旦基础架构到位,您就可以通过将适当的隐含带入范围来控制任何类型的“字符串化”。

    首先定义一个类型类:

    trait Stringable[T] extends (T => String)
    

    提供类型类的默认实现(它只是依赖于普通的toString方法):

    class DefaultStringable[T] extends Stringable[T] { 
       def apply(x: T) = x.toString
    }
    object DefaultStringable {
       implicit def any2stringable[T]: Stringable[T] = new DefaultStringable[T]
    }
    

    为您的用例实现类型类:

    implicit object DimIsStringable extends Stringable[ArrayBuffer[Int]] {
       def apply(buf: ArrayBuffer[Int]) = buf mkString "x"
    }
    

    定义使用类型类的打印方法:

    def myprintln[T](x: T)(implicit e: Stringable[T]) = e(x)
    

    趣味。

    import DefaultStringable._
    myprintln(ArrayBuffer(1,2,3)) // prints "ArrayBuffer(1, 2, 3)"
    

    利润!

    import DimIsStringable._
    myprintln(ArrayBuffer(1,2,3)) // prints "1x2x3"
    

    如果需要,您可以使默认类型类始终可用,而无需任何导入。为此,您将伴随模块中的转换提供给Stringable特征(如下所示)。这样做的缺点是,如果您忘记导入适当的Stringable,您将不再有编译器错误提醒您。

    object Stringable {
       implicit def any2stringable[T]: Stringable[T] = new DefaultStringable[T]
    }
    

答案 1 :(得分:3)

我不确定这是否符合神奇的条件,但这样可以吗?

class ArrayDim extends ArrayBufer[Int] {
   override def toString = mkString ("x")
}

编辑: 然后在你的多维数组类的代码中, 将dim = new ArrayBuffer替换为dim = new ArrayDim。根据您填充缓冲区的方式,您可能需要对代码进行细微更改。

答案 2 :(得分:1)

您可以使用隐式转换为具有暗淡方法的内容。这是一个例子:

scala> implicit def toDim(t: Traversable[_]) = new { def dim = t.mkString("x") }
toDim: (t: Traversable[_])java.lang.Object{def dim: String}

scala> List(1, 2, 3).dim
res0: String = 1x2x3

scala> ArrayBuffer(2, 2, 3).dim
res1: String = 2x2x3

答案 3 :(得分:0)

如果您愿意,可以在本地定义println,覆盖导入的定义:

def println(a : Any) = System.out.println(a match {
  case seq : Seq[_] => seq.mkString("x")
  case a@_ => a
}

println(scala.collection.mutable.ArrayBuffer(1,2,3)) // yields 1x2x3
println("Hello") //yields "Hello"

不幸的是,这不会影响Seq中变量的类型。可能有办法做到这一点,虽然我不确定,因为我们不能要求有一个清单。会有一个想法。