StringRiffle¶
Status: Stable
documented, exercised by the test suite and/or worked examples, with no known limitations recorded.
Description¶
StringRiffle[{s1, s2, ...}]
Joins the si into a string with spaces between them; nested lists use spaces at the lowest level and increasing numbers of newlines at higher levels. Non-string elements are converted with ToString.
StringRiffle[list, sep]
Inserts the string sep between the top-level elements.
StringRiffle[list, {"left", "sep", "right"}]
Joins with sep and wraps the result in the left/right delimiters.
StringRiffle[list, sep1, sep2, ...]
Inserts separator sep_i (a string or {left, sep, right}) between elements at level i.
Examples (12)¶
Every input below was run against the current Mathilda build and its output recorded.
Basic examples (4)¶
In[1]:= StringRiffle[{"a", "b", "c", "d", "e"}]
Out[1]= "a b c d e"
In[2]:= StringRiffle[{"a", "b", "c", "d", "e"}, ", "]
Out[2]= "a, b, c, d, e"
In[3]:= StringRiffle[{"a", "b", "c", "d", "e"}, {"(", " ", ")"}]
Out[3]= "(a b c d e)"
In[4]:= StringRiffle[{{"a", 27}, {"b", 28}, {"c", 29}}, {"{", ", ", "}"}, ": "]
Out[4]= "{a: 27, b: 28, c: 29}"
Applications (8)¶
Default scheme: a single space
A custom separator
A {left, sep, right} triple
Non-string elements are converted as ToString would
Nested: rows by newline, cells by space
One separator per level, outermost first
The inverse of StringSplit
The first argument must be a list: StringRiffle::list
Algorithm¶
stringriffle.c - StringRiffle builtin for Mathilda
StringRiffle assembles a string from a (possibly nested) list of elements by inserting separators between them - the inverse of StringSplit. Non-string leaves are converted with expr_to_string (so the integer 27 -> "27"); string leaves are used verbatim.
Forms:
StringRiffle[list] - default separator scheme: a
single space at the innermost level, one extra newline per level going
up (2-D: rows by "\n", cells by " "; 3-D: blocks by "\n\n", ...).
StringRiffle[list, sep] - string sep between the top-level
elements; deeper levels fall back to the default scheme.
StringRiffle[list, {"l","sep","r"}] - a 3-string list is a delimiter
triple: wrap the join with "l"..."r", joining with "sep".
StringRiffle[list, sep1, sep2, ...] - sep_i (a string or a delimiter
triple) between elements at level i (1 = outermost); deeper levels use
the default scheme.
Strings are treated as raw byte arrays (consistent with the rest of the string subsystem); no UTF-8 decoding is performed.
Implementation notes¶
Algorithm. builtin_stringriffle treats the first argument as the data and the rest as separators, one per level, with level 1 outermost. parse_sep reads each separator into a {left, sep, right} triple. A plain string becomes {"", sep, ""}, and a 3-string list is the triple itself. riffle_build then recurses over the data. A string leaf is copied verbatim, and any other leaf is rendered in OutputForm (expr_to_string_outputform, which is what ToString gives). Each level joins its children with its explicit separator. When a level has none, the default scheme applies, chosen by depth_from_bottom: one space at the innermost level, and one more newline for each level above it. It is the inverse of StringSplit.
Data structures. A SepSpec array that borrows the argument strings. The whole result is built in one growable RegexBuf, so each leaf is copied exactly once whatever the nesting depth, and the buffer is adopted into the result string. This replaced a build-each-level-then-concatenate design in v0.456 (3.6 ms ā 1.0 ms on the string benchmark).
Complexity / limits. O(total output). No arguments emits StringRiffle::argm. A first argument that is neither a list nor a string emits StringRiffle::list, and a malformed separator emits StringRiffle::string; both leave the call unevaluated. Not Listable, so it can see the whole nested structure.
Attributes: Protected.
References¶
See also: StringSplit, ToString
- Source:
src/strings/stringriffle.c - Specification:
docs/spec/builtins/string-operations.md - Tests:
tests/test_string_review.c - Tests:
tests/test_stringriffle.c
Notes & additional examples¶
Notes¶
StringRiffle[list, sep1, sep2, ...]joins a possibly nested list.sep_igoes between elements at leveli, counting from the outside. A separator is a string or a{left, sep, right}triple.- Levels without an explicit separator use the default scheme: one space at the innermost level and one more newline per level above it.
- String leaves are used verbatim, and any other leaf appears in its OutputForm.
- The result is built in one buffer, so each leaf is copied once whatever the depth (v0.456: 3.6 ms ā 1.0 ms on the string benchmark).
- See also:
StringJoin,StringSplit,Riffle.