Scala Массивы - красивая печать N-мерной матрицы - PullRequest
0 голосов
/ 09 апреля 2020

Я хочу создать метод, который печатает матрицу размера N (предопределенного типа, в данном случае double, с N неизвестным и фиксированной длиной массива) с предопределенным форматом. Например, в матрице 2 * 2 * 2 (куб. c) типа Double результат должен быть таким: :

[
    [
        [
            [0.0,0.0], [0.0,0.0]
        ],
        [
            [0.0,0.0], [0.0,0.0]
        ]
    ],
    [
        [
            [0.0,0.0], [0.0,0.0]
        ],
        [
            [0.0,0.0], [0.0,0.0]
        ]
    ]
]

. На данный момент я создал такой метод, который не делает требуемый отступ:

 def func(arr: Array[_]):String = {
    var output = for (a <- arr) yield {
      if ( a.isInstanceOf[Double] ) {
        a
      } else {
        func(a.asInstanceOf[Array[_]])
      }
    }
    output.mkString("[", ",", "]")
  }

Эффективен ли подход, который я использую? Можно ли использовать функцию обратного вызова? Не могли бы вы дать мне несколько советов?

1 Ответ

2 голосов
/ 09 апреля 2020

Вот рабочий пример с отступом:


 def func(arr: Array[_], pprintDeep:Int = 2, indentation:Int = 0):String = {
    val prefix1 = "  " * indentation
    val prefix2 = prefix1 + "  "

    val output = arr.map {
      case x: Array[_] => func(x, pprintDeep-1, indentation + 1) 
      case other if pprintDeep > 0 => prefix2 + other.toString
      case other => other.toString
    }

    if (pprintDeep > 0) output.mkString(s"$prefix1[\n", ",\n", s"\n$prefix1]")
    else prefix1 + output.mkString(s"[", ",", s"]")
}

Это хорошо? Скорее не лучший (объединяет много строк на месте). Мы должны использовать StringBuilder, если мы заботимся о производительности, но для случая с небольшим использованием все должно быть в порядке.

Несколько комментариев о вашем подходе:

  • a.isInstanceOf[Double] будет работать для double, но вы можете заботиться о большем количестве типов, и тогда такое дерево if ... else станет трудным для чтения и обслуживания. Используйте сопоставление с типами, как показано в моем примере.

  • Вы предполагали, что все, что не является двойным, является массивом ... рискованно. Используйте тип соответствия, как показано выше.

  • Если вы действительно заботитесь о производительности, вам нужно сравнить ее самостоятельно. Вы также можете использовать одну из существующих библиотек, которая распечатает ее для вас (например, lihaoyi.com/PPrint, lihaoyi.com/upickle)

  • рабочий код: https://scalafiddle.io/sf/YdGFHce/0

  • код, который также хорошо работает со строками: https://scalafiddle.io/sf/YdGFHce/10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...