www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - std.string.format call from varyargs

reply LeqxLeqx <LeqxLeqx protonmail.ch> writes:
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!
Jul 01
next sibling parent Nicholas Wilson <iamthewilsonator hotmail.com> writes:
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.
Jul 01
prev sibling parent reply "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
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.
Jul 01
parent reply drug <drug2004 bk.ru> writes:
02.07.2017 09:52, H. S. Teoh via Digitalmars-d-learn пишет:
 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
Cool! Is it D only or could be used in printf (C/C++)?
Jul 02
parent "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
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??
Jul 02