有没有一种 Smalltalk 方法来转置数组



>假设我有一个看起来像这样的数组

{ { #a . #b . #c } . 
  { #e . #f . #g } }.

有没有一种快速的方法可以把它变成

 { { #a . #e } . { #b . #f } . { #c . #g } }

该代码也应该适用于 n 元素子数组。

{ { #a . #b . #c . #d } . 
  { #e . #f . #g . #h } }.
{ #a . #b . #c } with: { #e . #f . #g } collect: [ :each1 :each2 | { each1 . each2 } ] 

会给你

#(#(#a #e) #(#b #f) #(#c #g))

通用一行,没有关于列或行计数的假设。

(1 to: rows first size) collect: [:column | rows collect: [:row | row at: column]]

一些Smalltalk甚至实现了:

SequenceableCollection>>keys
    ^1 to: self size

在这种情况下,第一个可以更好地实现为:

 rows first keys collect: [:column | rows collect: [:row | row at: column]]

不是很优雅,但它适用于几乎每个 Smalltalk 中任何大小的集合:

| results input |
input := { { #a . #b . #c } . 
  { #e . #f . #g } }.
results := Array new: input first size.
1 to: results size do: [ : subIndex | 
    results at: subIndex put: (input collect: [ : sub | sub at: subIndex ]) ].
results

如果您正在处理矩阵,我建议您创建 Matrix 类以及以下实例创建方法(类端(:

Matrix class >> fromBlock: aBlock numRows: n columns: m
    | matrix |
    matrix := self newRows: n columns: m.
    1 to: n do: [:i |
        1 to: m do: [:j | | aij |
            aij := aBlock value: i value: j.
            matrix atRow: i column: j put: aij]].
    ^matrix

然后,给定一个矩阵,您将使用此方法(实例端(转置它:

Matrix >> transposed
    ^self class
        fromBlock: [:i :j | self atRow: j column: i]
        numRows: self numColumns
        columns: self numRows

最新更新