Search code examples
smalltalksqueak

Skipping every other array element


So Im trying to skip past every other element and enter them into a collection. I am then converting the collection back to an array and trying to return it. Im not sure whats wrong though.

altElement

    | newColl x y |
    newColl:= OrderedCollection new.

          x := 1.
          [x <= self size ] whileTrue: [x := x + 2 |
        newColl add: (self at: x)].

        y:= newColl asArray.

        ^y

Solution

  • Another, more cross dialect variant, is to remember that intervals are collections too (I find this more functional as well).

    | sequence |
    sequence = #('I' 'invented' 'the' 'term' 'Object' 'Oriented' 'Programming' 'and' 'this' 'is' 'not' 'it').
    (1 to: sequence size by: 2) collect: [:n | sequence at: n]
    

    will return:

    #('I' 'the' 'Object' 'Programming' 'this' 'not')
    

    But can be easily changed to return

    #('invented' 'term' 'Oriented' 'and' 'is' 'it')
    

    by simply swapping the leading 1 for a 2. What's nice though, is that you can slice it any way you want. If your dialect has a pairsCollect:, you can only use it for adjacent items. You can't get every third word starting two from the back in backwards order:

    (sequence size - 1 to: 1 by: -3) collect: [:n | sequence at: n]
    "returns"
    #('not' 'and' 'Object' 'invented')
    

    I find that using the sequence as a slice iterator to collect: is a far more useful and general pattern to use.