std.string.format call from varyargs

H. S. Teoh via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Jul 1 23:52:20 PDT 2017


On Sun, Jul 02, 2017 at 12:49:30AM +0000, LeqxLeqx via Digitalmars-d-learn wrote:
> Hello!
> 
> How does one go about invoking a templated-variatic function such as
> std.string.format with an array of objects?
> 
> For example:
> 
> string stringMyThing (string formatForMyThings, MyThing[] myThings)
> {
>   return format(
>     formatForMyThings,
>     myThings
>     );
> }
> 
> 
> 
> In executing the above, the 'format' method always interprets the
> entire array 'myThings' as the first argument to the format, and no
> arguments afterwards, resulting in 'orphaned' format specifiers if the
> array is longer than a single element. Even if the array is only a
> single element, the formatter will wrap the result of the element's
> 'toString()' method with '[' and ']'
> 
> I really don't want to write my own format parser.
> Any help would be much appreciated!
[...]

Take a look at the docs that describe the "%(...%)" nested format
specifiers.  For example:

	int[] arr = [ 1, 2, 3 ];
	writefln("%(%s | %)", arr);

Output:

	1 | 2 | 3

Explanation: %(...%) means a nested format specifier, where the stuff
enclosed between %( and %) are applied to each array element (actually,
range element -- it works for arbitrary input ranges). In this case, the
stuff in between is "%s | ", which is treated as "%s" followed by the
delimiter " | ". So each array element is formatted with %s, and " | "
is inserted as a delimiter.

A slightly more interesting example:

	int[] arr = [ 1, 2, 3 ];
	writefln("%(<%s>%|, %)", arr);

Output:

	<1>, <2>, <3>

Explanation: the stuff between %( and %) is "<%s>%|, ", which is
understood as applying "<%s>" to each array element, and treating ", "
as the delimiter. The "%|" separates the per-element component from the
delimiter; this distinction is important because we want the ">" to
appear after every element including the last one, but we don't want the
", " to appear after the last element.

You can also nest %(...%) to handle multidimensional arrays. Here's my
favorite example:

	auto m = [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ];
	writefln("%([ %(%s, %) ]%|\n%)", m);

Output:

	[ 1, 2, 3 ]
	[ 4, 5, 6 ]
	[ 7, 8, 9 ]

Hope this helps!


T

-- 
Tech-savvy: euphemism for nerdy.


More information about the Digitalmars-d-learn mailing list