2

假设我有以下矩阵:


val grid = Array(
  Array( 1, 2, 3,  4, 5, 6,  7, 8, 9), 
  Array(11,12,13, 14,15,16, 17,18,19), 
  Array(21,22,23, 24,25,26, 27,28,29), 

  Array(31,32,33, 34,35,36, 37,38,39), 
  Array(41,42,43, 44,45,46, 47,48,49), 
  Array(51,52,53, 54,55,56, 57,58,59), 

  Array(61,62,63, 64,65,66, 67,68,69), 
  Array(71,72,73, 74,75,76, 77,78,79), 
  Array(81,82,83, 84,85,86, 87,88,89)
)

我怎样才能,最好以功能方式,将它们转换为这个矩阵:


val gridWithFields = Array(
  Array(1,2,3, 11,12,13, 21,22,23),
  Array(4,5,6, 14,15,16, 21,22,23),
  Array(7,8,9, 17,18,19, 27,28,29),
  ... 
)

*更新*
我做了一些基准测试,但不确定内存结果是否正确。无论如何,它们是:

@maxmc for 的解决方案

周期中的 alg1:10 时间:2712683ns 内存:459572
周期中的 alg1:100 时间:914297ns 内存:458191
周期中的 alg1:1000 时间:85102ns 内存:457944
周期中的 alg1:10000 时间:68742ns 内存:457943

@Daniel C. Sobral 解决方案

周期中的 alg2:10 时间:3747031ns 内存:458889
循环中的 alg2:100 时间:1796564ns 内存:457951
循环中的 alg2:1000 时间:186215ns 内存:457220
循环中的 alg2:10000 时间:122642ns 内存:456708

@Or Peles 解决方案

周期中的 alg3:10 时间:741475ns 内存:457472
循环中的 alg3:100 时间:542181ns 内存:457914
循环中的 alg3:1000 时间:248020ns 内存:457911
循环中的 alg3:10000 时间:119105ns 内存:457919

@Hbf 解决方案

周期中的 alg4:10 时间:179093ns 内存:457472
循环中的 alg4:100 时间:121072ns 内存:457069
循环中的 alg4:1000 时间:78123ns 内存:456719
循环中的 alg4:10000 时间:75948ns 内存:455913

@Eastsun 解决方案

周期中的 alg5:10 时间:144037ns 内存:457512
循环中的 alg5:100 时间:40672ns 内存:457059
循环中的 alg5:1000 时间:42236ns 内存:456119
循环中的 alg5:10000 时间:46480ns 内存:455952

我已经在 MacMini(2012) 上对其进行了测试。内存结果真的很奇怪,所以来源在这里,如果有一些不好的错误和反模式请告诉我=)https://github.com/Stimphonier/MatrixBench

4

7 回答 7

4

'for' 方法:

for(x <- 0 until 9 by 3) yield
  (for {
    row <- 0 until 9;
    col <- x until x + 3 by 3;
    i <- col until col + 3
  } yield grid(row)(i)).toArray   
于 2013-02-26T14:43:50.017 回答
4

分组和转置。我将展示我找出正确顺序的 REPL 会话。

首先,你的数据中有一个分组——你用空格清楚地表明了这一点。每三行,每行内每三个元素。所以我们要做的第一件事就是明确分组。

scala> grid.map(row => (row grouped 3).toArray)
res7: Array[Array[Array[Int]]] = Array(Array(Array(1, 2, 3), Array(4, 5,
 6), Array(7, 8, 9)), Array(Array(11, 12, 13), Array(14, 15, 16), Array(
17, 18, 19)), Array(Array(21, 22, 23), Array(24, 25, 26), Array(27, 28,
29)), Array(Array(31, 32, 33), Array(34, 35, 36), Array(37, 38, 39)), Ar
ray(Array(41, 42, 43), Array(44, 45, 46), Array(47, 48, 49)), Array(Arra
y(51, 52, 53), Array(54, 55, 56), Array(57, 58, 59)), Array(Array(61, 62
, 63), Array(64, 65, 66), Array(67, 68, 69)), Array(Array(71, 72, 73), A
rray(74, 75, 76), Array(77, 78, 79)), Array(Array(81, 82, 83), Array(84,
 85, 86), Array(87, 88, 89)))

scala> (res7 grouped 3).toArray
res8: Array[Array[Array[Array[Int]]]] = Array(Array(Array(Array(1, 2, 3)
, Array(4, 5, 6), Array(7, 8, 9)), Array(Array(11, 12, 13), Array(14, 15
, 16), Array(17, 18, 19)), Array(Array(21, 22, 23), Array(24, 25, 26), A
rray(27, 28, 29))), Array(Array(Array(31, 32, 33), Array(34, 35, 36), Ar
ray(37, 38, 39)), Array(Array(41, 42, 43), Array(44, 45, 46), Array(47,
48, 49)), Array(Array(51, 52, 53), Array(54, 55, 56), Array(57, 58, 59))
), Array(Array(Array(61, 62, 63), Array(64, 65, 66), Array(67, 68, 69)),
 Array(Array(71, 72, 73), Array(74, 75, 76), Array(77, 78, 79)), Array(A
rray(81, 82, 83), Array(84, 85, 86), Array(87, 88, 89))))

让我们看看我们是否做对了:

scala> res8(0)
res9: Array[Array[Array[Int]]] = Array(Array(Array(1, 2, 3), Array(4, 5,
 6), Array(7, 8, 9)), Array(Array(11, 12, 13), Array(14, 15, 16), Array(
17, 18, 19)), Array(Array(21, 22, 23), Array(24, 25, 26), Array(27, 28,
29)))

是的,这正是我们要转换的数据单位。让我们试一试:

scala> res9.transpose
res10: Array[Array[Array[Int]]] = Array(Array(Array(1, 2, 3), Array(11,
12, 13), Array(21, 22, 23)), Array(Array(4, 5, 6), Array(14, 15, 16), Ar
ray(24, 25, 26)), Array(Array(7, 8, 9), Array(17, 18, 19), Array(27, 28,
 29)))

如预期的!因此,让我们对整个矩阵进行操作:

scala> res8 map (_.transpose)
res11: Array[Array[Array[Array[Int]]]] = Array(Array(Array(Array(1, 2, 3
), Array(11, 12, 13), Array(21, 22, 23)), Array(Array(4, 5, 6), Array(14
, 15, 16), Array(24, 25, 26)), Array(Array(7, 8, 9), Array(17, 18, 19),
Array(27, 28, 29))), Array(Array(Array(31, 32, 33), Array(41, 42, 43), A
rray(51, 52, 53)), Array(Array(34, 35, 36), Array(44, 45, 46), Array(54,
 55, 56)), Array(Array(37, 38, 39), Array(47, 48, 49), Array(57, 58, 59)
)), Array(Array(Array(61, 62, 63), Array(71, 72, 73), Array(81, 82, 83))
, Array(Array(64, 65, 66), Array(74, 75, 76), Array(84, 85, 86)), Array(
Array(67, 68, 69), Array(77, 78, 79), Array(87, 88, 89))))

现在我们只需要将其展平即可。我们需要以与分组相反的顺序将其展平:

scala> res11.flatten
res12: Array[Array[Array[Int]]] = Array(Array(Array(1, 2, 3), Array(11,
12, 13), Array(21, 22, 23)), Array(Array(4, 5, 6), Array(14, 15, 16), Ar
ray(24, 25, 26)), Array(Array(7, 8, 9), Array(17, 18, 19), Array(27, 28,
 29)), Array(Array(31, 32, 33), Array(41, 42, 43), Array(51, 52, 53)), A
rray(Array(34, 35, 36), Array(44, 45, 46), Array(54, 55, 56)), Array(Arr
ay(37, 38, 39), Array(47, 48, 49), Array(57, 58, 59)), Array(Array(61, 6
2, 63), Array(71, 72, 73), Array(81, 82, 83)), Array(Array(64, 65, 66),
Array(74, 75, 76), Array(84, 85, 86)), Array(Array(67, 68, 69), Array(77
, 78, 79), Array(87, 88, 89)))

scala> res12.map(_.flatten)
res13: Array[Array[Int]] = Array(Array(1, 2, 3, 11, 12, 13, 21, 22, 23),
 Array(4, 5, 6, 14, 15, 16, 24, 25, 26), Array(7, 8, 9, 17, 18, 19, 27,
28, 29), Array(31, 32, 33, 41, 42, 43, 51, 52, 53), Array(34, 35, 36, 44
, 45, 46, 54, 55, 56), Array(37, 38, 39, 47, 48, 49, 57, 58, 59), Array(
61, 62, 63, 71, 72, 73, 81, 82, 83), Array(64, 65, 66, 74, 75, 76, 84, 8
5, 86), Array(67, 68, 69, 77, 78, 79, 87, 88, 89))

或者,作为一个班轮:

grid.map(_.grouped(3).toArray).grouped(3).toArray.map(_.transpose).flatten.map(_.flatten)
于 2013-02-26T14:49:32.793 回答
3
val n: Array[Array[Int]] =
  grid.grouped(3)
      .toArray
      .flatMap(_.map(_.grouped(3).toArray)
                .transpose
                .map(_.flatten))

n.foreach(r => {r.foreach(e => print(e + " ")); println})

// 1 2 3 11 12 13 21 22 23 
// 4 5 6 14 15 16 24 25 26 
// 7 8 9 17 18 19 27 28 29 
// 31 32 33 41 42 43 51 52 53 
// 34 35 36 44 45 46 54 55 56 
// 37 38 39 47 48 49 57 58 59 
// 61 62 63 71 72 73 81 82 83 
// 64 65 66 74 75 76 84 85 86 
// 67 68 69 77 78 79 87 88 89

应该可以toArray通过将相应的implicit def放入范围来删除显式调用。

于 2013-02-26T14:27:40.067 回答
2

那这个呢?

type Grid = Array[Array[Int]]

def transform(grid: Grid): Grid = {
  def transformLine(grid: Grid) =
    grid.map(_.grouped(3).toArray).transpose.map(_.flatten)
  grid.grouped(3).flatMap(transformLine).toArray
}

scala> transform(grid) map(_.deep) foreach println
Array(1, 2, 3, 11, 12, 13, 21, 22, 23)
Array(4, 5, 6, 14, 15, 16, 24, 25, 26)
Array(7, 8, 9, 17, 18, 19, 27, 28, 29)
Array(31, 32, 33, 41, 42, 43, 51, 52, 53)
Array(34, 35, 36, 44, 45, 46, 54, 55, 56)
Array(37, 38, 39, 47, 48, 49, 57, 58, 59)
Array(61, 62, 63, 71, 72, 73, 81, 82, 83)
Array(64, 65, 66, 74, 75, 76, 84, 85, 86)
Array(67, 68, 69, 77, 78, 79, 87, 88, 89)

由于大量隐式转换和中间结果,效率完全低下,但它是功能性的,不应该成为问题,除非你需要在一秒钟内执行数百次......

于 2013-02-26T14:26:44.863 回答
2

这是一个简短而有效的解决方案,可能是最短和最有效的解决方案:

scala> val matrix = Array.tabulate(9, 9){ (r, c) => grid(r/3*3+c/3)(r%3*3+c%3) }
matrix: Array[Array[Int]] = 
Array(Array(1, 2, 3, 11, 12, 13, 21, 22, 23), 
      Array(4, 5, 6, 14, 15, 16, 24, 25, 26), 
      Array(7, 8, 9, 17, 18, 19, 27, 28, 29), 
      Array(31, 32, 33, 41, 42, 43, 51, 52, 53), 
      Array(34, 35, 36, 44, 45, 46, 54, 55, 56), 
      Array(37, 38, 39, 47, 48, 49, 57, 58, 59), 
      Array(61, 62, 63, 71, 72, 73, 81, 82, 83), 
      Array(64, 65, 66, 74, 75, 76, 84, 85, 86), 
      Array(67, 68, 69, 77, 78, 79, 87, 88, 89)
)
于 2013-02-27T03:47:29.463 回答
1

快速而肮脏(但功能强大)的黑客:

(0 until grid(0).size/3).toArray.
  map(i =>
    grid.flatMap(a => a.drop(i*3).take(3))
  )

对于grid您提供的,这会产生:

Array(
  Array(1, 2, 3, 11, 12, 13, 21, 22, 23, /*...*/, 71, 72, 73, 81, 82, 83),
  Array(4, 5, 6, 14, 15, 16, 24, 25, 26, /*...*/, 74, 75, 76, 84, 85, 86), 
  Array(7, 8, 9, 17, 18, 19, 27, 28, 29, /*...*/, 77, 78, 79, 87, 88, 89)
)
于 2013-02-26T14:10:14.073 回答
1

在一行中:

grid.grouped(3).map(g => g.transpose.grouped(3).map(_.flatten.sorted)).flatten.toArray

res25: Array[Array[Int]] = Array(Array(1, 2, 3, 11, 12, 13, 21, 22, 23), Array(4, 5, 6, 14, 15, 16, 24, 25 , 26), 数组(7, 8, 9, 17, 18, 19, 27, 28, 29), 数组(3 1, 32, 33, 41, 42, 43, 51, 52, 53), 数组(34 , 35, 36, 44, 45, 46, 54, 55, 56), A ray(37, 38, 39, 47, 48, 49, 57, 58, 59), Array(61, 62, 63, 71, 72, 73, 81, 82, 83), 数组(64, 65, 66, 74, 75, 76, 84, 85, 86), 数组(67, 68, 69, 77, 78, 79, 87, 88, 89))

于 2013-02-26T14:36:57.693 回答