splitBy: to sequence.slate

=?X-UNKNOWN?Q?Olli_Pietil=E4inen?= ollip at freeshell.org
Wed Jul 21 12:31:56 PDT 2004


On Wed, 21 Jul 2004, Brian T. Rice wrote:

> Here's a slightly tweaked version of it:
>
> s@(Sequence traits) splitIntoSize: n
> "Answers the result of splitting the sequence into n-sized sequences.
> If size of the sequence is not divisible by n, the last element will be
> smaller."
> [| subSeqs sepIndex nextSeq remainder |
>   n isPositive ifFalse: [error: 'Split size must be positive.'].
>   n >= s size ifTrue: [^ {s copy}].
>   subSeqs: (Array newSize: s size // n + 1) writer.
>   sepIndex: 0.
>   [sepIndex < (s size - (s size mod: n))]
>      whileTrue: [nextSeq: (s copyFrom: sepIndex to: sepIndex + n - 1).
>                  subSeqs nextPut: nextSeq.
>                  sepIndex: sepIndex + n].
>   sepIndex = s size
>      ifFalse: [remainder: (s copyFrom: sepIndex to: s indexLast).
>                subSeqs addLast: remainder].
>   subSeqs contents
> ].

Looks better than my version, but has a bug in it now.  When there is a
remainder, it doesn't get added to subSeqs because WriteStream doesn't
have addLast: defined on. Changing addLast: to nextPut: corrects
it. Thus the working code:

s@(Sequence traits) splitIntoSize: n
"Answers the result of splitting the sequence into n-sized sequences.
If size of the sequence is not divisible by n, the last element will be
smaller."
[| subSeqs sepIndex nextSeq remainder |
    n isPositive ifFalse: [error: 'Split size must be positive.'].
    n >= s size ifTrue: [^ {s copy}].
    subSeqs: (Array newSize: s size // n + 1) writer.
    sepIndex: 0.
    [sepIndex < (s size - (s size mod: n))]
       whileTrue: [nextSeq: (s copyFrom: sepIndex to: sepIndex + n - 1).
                   subSeqs nextPut: nextSeq.
                   sepIndex: sepIndex + n].
    sepIndex = s size
       ifFalse: [remainder: (s copyFrom: sepIndex to: s indexLast).
                 subSeqs nextPut: remainder].
    subSeqs contents
].

Is this correct now?

> I added a failure mode where the whole sequence is copied and returned as the
> one result if you ask for a larger split-size than what it has, as it's
> returning 0 full-size elements and one "fractional".

Ah, of course. Didn't think of it that way, but that's definately
right. Seems so obvious now :)

>> I don't know if this is a good name for it. Maybe groupBy: would be better?
>
> src/group.slate actually defines groupBy: to return a Grouping, kind of like
> SQL's "group by". splitIntoSize: is what occurred to me. Does that sound
right?

Sounds right to me. Much more understandable than splitBy:.


Olli




More information about the Slate mailing list