join_by

Definition: sequence res = join_by(sequence s, integer step, integer n, object step_pad="   ", object n_pad="\n")
Description: The join_by routine allows columnisation of results across the screen for easier reading.

Best illustrated by example, join_by iteratively interleaves up to n blocks of size step with step_pad, before joining with n_pad, repeated as necessary up to length(s) - however, typically you would experiment with different values until finding a layout that you like, so fully "grokking" what this really does is not particularly helpful, anyway.

Segments are expected to be padded to a consistent length, before this routine is called, to achieve proper alignment.

Note that n_pad is duplicated between each (n*step)-block, but only occurs once at the end, unless a trailing "" is supplied.

Uses join internally. The default for step_pad is three spaces. Returns a string or sequence.
Example 1:
sequence s = {"A","B","C","D","E","F","G","H","I","J","K","L"}

puts(1,join_by(s,3,2))  puts(1,"=\n")
--  A   D
--  B   E
--  C   F
--
--  G   J
--  H   K
--  I   L
--  =
puts(1,join_by(s,2,3))  puts(1,"=\n")
--  A   C   E
--  B   D   F
--
--  G   I   K
--  H   J   L
--  =
puts(1,join_by(s,3,4))  puts(1,"=\n")   -- (join_by(s,3,5) same)
--  A   D   G   J
--  B   E   H   K
--  C   F   I   L
--  =
puts(1,join_by(s,4,3))  puts(1,"=\n")   -- (join_by(s,4,4) same)
--  A   E   I
--  B   F   J
--  C   G   K
--  D   H   L
--  =
puts(1,join_by(s,2,5))  puts(1,"=\n")   -- (see note)
--  A   C   E   G   I
--  B   D   F   H   J
--
--  K
--  L
--  =
puts(1,join_by(s,5,2))  puts(1,"=\n")   -- (join_by(s,5,3) same, see notes)
--  A   F
--  B   G
--  C   H
--  D   I
--  E   J
--
--  K
--  L
--  =
puts(1,join_by(s,1,4))  puts(1,"=\n")
--  A   B   C   D
--
--  E   F   G   H
--
--  I   J   K   L
--  =
puts(1,join_by(s,1,6))  puts(1,"=\n")
--  A   B   C   D   E   F
--
--  G   H   I   J   K   L
--  =
puts(1,join_by(s,1,5))  puts(1,"=\n")
--  A   B   C   D   E
--
--  F   G   H   I   J
--
--  K   L
--  =

(Obviously the puts(1,"=\n") make the output easier to follow: without them, each example starts on a new line, however blank lines occur mid-example, but not between examples.)

Note how in the "heightwise" (step>1) examples 5 and 6 the trailing (partial) n-blocks retain the step-pattern, as of course does the last "widthwise" (step=1) example. Should you wish to "flatten" the trailing partial block in an otherwise heightwise invocation, I suggest you spilt s into n-wise whole sets and the rest, and invoke join_by twice, with some different step & n on the partial block(s), which could have all manner of desired shapes for the partial>step cases, and therefore it is not really feasible to automate that reliably.

In the 6th example, with n=3, you might want the final K L up in column 3, however the routine as-is cannot do that.
The implementation can be found in builtins\pflatten.e and contains the (lightly tested and) commented-out changes required to automatically output a trailing partial<=step widthwise. There may also be some partial<=(or>)n cases (where that differs from partial<=(or>)step) which merit a subtly different approach, and that is the reason why I said lightly tested and left those changes commented-out.
Example 2: demo/rosetta/IQpuzzle.exw
See Also: join, columnize