Re: std.format range with compound format specifiers?

2019-11-19 Thread Steven Schveighoffer via Digitalmars-d-learn

On 11/19/19 7:28 PM, Petar Kirov [ZombineDev] wrote:


In cases where I have some aggregate data, but I don't feel like writing 
a custom toString method, I often wrap the data in a Tuple and use its 
[1] %(inner%) or %(inner%|sep%) format specifiers. Here's an example:


import std;
void main()
{
     {
     alias NV = tuple;
     auto arr = [NV("Steve", 1), NV("George", 500), NV("Adam", -5)];
     writefln("%(%(%s: %s%), %)", arr);
     }

     {
     static struct NV
     {
     string name;
     int value;
     }
     auto arr = [NV("Steve", 1), NV("George", 500), NV("Adam", -5)];
     writefln("%(%(%s: %s%), %)", arr.map!(obj => obj.tupleof.tuple));
     }
}

In this case, from outside to inside, I am first formatting the range 
and then for each tuple I am formatting its fields one by one.


Sweet! This is exactly what I was looking for.

If for exmaple I want to format a tuple with 3 double, each one of them 
with a different number of digits after the decimal point, I could do:

"%(%.1f %.2f %.3f%)".writefln(tuple(1.5, 1.25, 1.125));


Nice. I think this should work well for me.

I think we should extend std.format with support for using the same 
tuple formatting specifier as std.typecons.Tuple, but for structs and 
possibly classes, as I find it quite useful.


Yes. At least the mechanism you describe should be pasted into 
formattedWrite's spec as I had no idea about it, and I would not think 
to look at tuple docs for the answer.


A format spec that indicates formattedWrite should use tupleof and treat 
it the same would be nice instead of having to do map.tupleof.tuple.


-Steve


Re: std.format range with compound format specifiers?

2019-11-19 Thread Petar via Digitalmars-d-learn
On Tuesday, 19 November 2019 at 21:50:08 UTC, Steven 
Schveighoffer wrote:
I know I can format a range with a format string that contains 
%(%s, %). And this results in a nice comma separated list for 
each item.


But what about an item that has a not-so-cookie-cutter format? 
Like for instance a name/value field:


struct NV
{
  string name;
  int value;
}

If I want to print one of these, I can do:

format("%s: %s", nv.name, nv.value);

If I wanted to print a range of these, let's say:

auto arr = [NV("Steve", 1), NV("George", 500), NV("Adam", -5)];

How can I have it come out like:

Steve: 1, George: 500, Adam: -5

Do I have to define a toString method in the NV struct? Is 
there not another way besides doing this?


-Steve


In cases where I have some aggregate data, but I don't feel like 
writing a custom toString method, I often wrap the data in a 
Tuple and use its [1] %(inner%) or %(inner%|sep%) format 
specifiers. Here's an example:


import std;
void main()
{
{
alias NV = tuple;
auto arr = [NV("Steve", 1), NV("George", 500), NV("Adam", 
-5)];

writefln("%(%(%s: %s%), %)", arr);
}

{
static struct NV
{
string name;
int value;
}
auto arr = [NV("Steve", 1), NV("George", 500), NV("Adam", 
-5)];
writefln("%(%(%s: %s%), %)", arr.map!(obj => 
obj.tupleof.tuple));

}
}

In this case, from outside to inside, I am first formatting the 
range and then for each tuple I am formatting its fields one by 
one.


If for exmaple I want to format a tuple with 3 double, each one 
of them with a different number of digits after the decimal 
point, I could do:

"%(%.1f %.2f %.3f%)".writefln(tuple(1.5, 1.25, 1.125));

If on the other hand I want to format all tuple elements the 
same, I would use this scheme:

"%(%.1f%| %)".writefln(tuple(1.5, 1.25, 1.125));

I think we should extend std.format with support for using the 
same tuple formatting specifier as std.typecons.Tuple, but for 
structs and possibly classes, as I find it quite useful.


[1]: https://dlang.org/phobos/std_typecons#.Tuple.toString


std.format range with compound format specifiers?

2019-11-19 Thread Steven Schveighoffer via Digitalmars-d-learn
I know I can format a range with a format string that contains %(%s, %). 
And this results in a nice comma separated list for each item.


But what about an item that has a not-so-cookie-cutter format? Like for 
instance a name/value field:


struct NV
{
  string name;
  int value;
}

If I want to print one of these, I can do:

format("%s: %s", nv.name, nv.value);

If I wanted to print a range of these, let's say:

auto arr = [NV("Steve", 1), NV("George", 500), NV("Adam", -5)];

How can I have it come out like:

Steve: 1, George: 500, Adam: -5

Do I have to define a toString method in the NV struct? Is there not 
another way besides doing this?


-Steve