Thread overview | |||||
---|---|---|---|---|---|
|
November 19, 2019 std.format range with compound format specifiers? | ||||
---|---|---|---|---|
| ||||
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 |
November 20, 2019 Re: std.format range with compound format specifiers? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 |
November 19, 2019 Re: std.format range with compound format specifiers? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Petar Kirov [ZombineDev] | 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 |
Copyright © 1999-2021 by the D Language Foundation