Re: std.string.format call from varyargs

2017-07-02 Thread H. S. Teoh via Digitalmars-d-learn
On Sun, Jul 02, 2017 at 11:38:34AM +0300, drug via Digitalmars-d-learn wrote:
> 02.07.2017 09:52, H. S. Teoh via Digitalmars-d-learn пишет:
[...]
> > 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!
[...]
> Cool! Is it D only or could be used in printf (C/C++)?

AFAIK, this is a D-specific extension.


T

-- 
Why do conspiracy theories always come from the same people??


Re: std.string.format call from varyargs

2017-07-02 Thread drug via Digitalmars-d-learn

02.07.2017 09:52, H. S. Teoh via Digitalmars-d-learn пишет:

On Sun, Jul 02, 2017 at 12:49:30AM +, 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


Cool! Is it D only or could be used in printf (C/C++)?


Re: std.string.format call from varyargs

2017-07-02 Thread H. S. Teoh via Digitalmars-d-learn
On Sun, Jul 02, 2017 at 12:49:30AM +, 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.


Re: std.string.format call from varyargs

2017-07-01 Thread Nicholas Wilson via Digitalmars-d-learn

On Sunday, 2 July 2017 at 00:49:30 UTC, LeqxLeqx 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!


Thanks!


string stringMyThing (string fmt, MyThing[]  myThings)
{
Appender!(string) s;
foreach(thing; myThings);
s.append(format(fmt,thing));
return s.data();
 }

sorry I can't remember the appender api properly.