是否有Smalltalk方法来转置数组?

时间:2014-08-24 22:18:30

标签: collections smalltalk transpose pharo

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

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

是否可以快速将其转换为

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

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

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

4 个答案:

答案 0 :(得分:4)

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

会给你

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

答案 1 :(得分:3)

不太优雅,但它适用于几乎所有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

答案 2 :(得分:3)

通用单线,没有关于列数或行数的假设。

(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]]

答案 3 :(得分:0)

如果您正在处理矩阵,我建议创建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