Expand/Shrink

columnize

Definition: sequence res = columnize(sequence source, object columns={}, object defval=0)
Description: Convert a set of sequences into a set of columns.
Any atoms found in source are treated as if they were a 1-element sequence.
The optional columns parameter can be a specific column number or an ordered set.
The default value is used when some elements of source have different lengths.

Returns a sequence of sequences (or strings), one for each required column.
Comments: Can make it much easier to declare related items yet still be able to use a plain find().

To obtain a different view/ordering of the results of columnize, a tagsort is recommended.
Example 1: Perform a standard table inversion or just pick out the desired items
?columnize({{1, 2}, {3, 4}, {5, 6}})            -- {{1,3,5}, {2,4,6}}
?columnize({{1, 2}, {3, 4}, {5, 6, 7}})         -- {{1,3,5}, {2,4,6}, {0,0,7}}
?columnize({{1}, {2}, {3, 4}},defval:=-999)     -- {{1,2,3}, {-999,-999,4}}
?columnize({{1, 2}, {3, 4}, {5, 6, 7}}, 2)      -- {{2,4,6}}
?columnize({{1, 2}, {3, 4}, {5, 6, 7}}, {2,1})  -- {{2,4,6}, {1,3,5}}
Example 2: Use a space defval if you want strings back:
?columnize({"abc", "def", "ghi"},defval:=' ')   -- {"adg", "beh", "cfi" }

Otherwise you would actually get {{97'a',100'd',103'g'},{98'b',101'e',104'h'},{99'c',102'f',105'i'}} returned - your program (including printf("%s") etc) should still work, however debugging/ex.err/pp()/? will be harder to decipher.
Example 3: Declare logically related items together but generate several separate matching tables, suitable for find() or (perhaps/if strictly in order) binary_search().
constant {field,desc,val} = columnize({{"field1", "desc1",5},
                                       {"field2", "desc2",3}})
constant {knowntags, knowntagdescs} = columnize({
         {MI_SIGNATURE,  "Module info signature"},
         {MI_FILENAME,   "Record with full path of executable"},
         {MI_RTP,        "RTP"},
       $},{1,2})
-- which is equivalent to:
constant field = {"field1", "field2"},
         desc = {"desc1", "desc2"}
         val = {5,3}
constant knowntags = {MI_SIGNATURE,MI_FILENAME,MI_RTP},
         knowntagdescs = {"Module info signature",
                          "Record with full path of executable",
                          "RTP"}

This may save considerable effort when you have hundreds of fields: major chance for mishap as well as eyebrainandcursorfingerache, were it not for columnize().

Also note that plade.exw required (for want of a better term) nested use of columnize; instead of
constant {{iupnames,iuprids}, cem, sigs, icons, ...} = columnize({...})

the desired 5+ matching tables were achieved through
constant {iupnamerids, cem, sigs, icons, ...} = columnize({...})
constant {iupnames,iuprids} = columnize(iupnamerids)
Implementation: See builtins\pcolumn.e (an autoinclude) for details of the actual implementation.
See Also: join, tagset