Is there a Smalltalk way to wrap an array?

Suppose I have an array that looks like this:

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

      

Is there a quick way to turn this into

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

      

the code should work for n-element subarrays too.

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

      

+3


source to share


4 answers


General purpose general slot, no assumptions about the number of columns or rows.

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

      

Some Smalltalk even implement:



SequenceableCollection>>keys
    ^1 to: self size

      

In this case, the former can be implemented even better:

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

      

+3


source


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

      

will provide you



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

      

+4


source


Not very elegant, but it works for collections of any size in almost every 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

      

+3


source


If you are dealing with matrices, I would suggest creating a Matrix class along with this instantiation method (class):

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

      

Then, given the matrix, you have to transpose it with this method (instance side):

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

      

0


source







All Articles