www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Formatted output of range of tuples

reply "antropod" <antropod gmail.com> writes:
Hello!

Consider this code:

+++
import std.stdio;
import std.range;
import std.algorithm;

void printIndexedArray1(T, Range)(T[] source, Range indexes)
{
	foreach(row; zip(indexes, source))
	{
		foreach(col; row) {
			write(col, " ");
		}
		writeln;
	}
}

void printIndexedArray2(T, Range)(T[] source, Range indexes)
{
	writef("%(%(%s %)\n%)", zip(indexes, source));
}

void main()
{
	uint[] data = [17, 30, 48, 140, 10, 01, 126, 138, 140, 3, 501];
	printIndexedArray1(data, sequence!"n");
	printIndexedArray2(data, sequence!"n");

}
+++

Looks fairly straightforward. But, the second function causes 
compilation error:

std.format.FormatException C:\D\dmd2\windows\bin\..\..\src\phobos\std\format.d(2
585): Expected '%s' format specifier for type 'Tuple!(uint, uint)'

Can you help me with that?
Oct 08 2014
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
antropod:

 Looks fairly straightforward. But, the second function causes 
 compilation error:

 std.format.FormatException C:\D\dmd2\windows\bin\..\..\src\phobos\std\format.d(2
 585): Expected '%s' format specifier for type 'Tuple!(uint, 
 uint)'

 Can you help me with that?
Currently the "%(%s%)" formatting doesn't support tuples as sequences of values. For indexes now there is also "enumerate". Bye, bearophile
Oct 08 2014
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 10/08/2014 02:31 PM, bearophile wrote:

 For indexes now there is also "enumerate".

 Bye,
 bearophile
Thanks for the tip. std.range.enumerate makes a big difference: foreach (i, element; MyRange(42).enumerate) { // ... } versus sequence!"n" and zip: foreach (i, element; zip(sequence!"n", MyRange(42))) { // ... } Ali
Oct 12 2014
parent "bearophile" <bearophileHUGS lycos.com> writes:
Ali Çehreli:

     foreach (i, element; MyRange(42).enumerate) {
         // ...
     }

 versus sequence!"n" and zip:

     foreach (i, element; zip(sequence!"n", MyRange(42))) {
         // ...
     }
But it's better to not use automatic unpacking of tuples. See issues 7361 and especially 9817. Bye, bearophile
Oct 13 2014
prev sibling parent reply "anonymous" <anonymous example.com> writes:
On Wednesday, 8 October 2014 at 21:21:47 UTC, antropod wrote:
 Hello!

 Consider this code:

 +++
 import std.stdio;
 import std.range;
 import std.algorithm;

 void printIndexedArray1(T, Range)(T[] source, Range indexes)
 {
 	foreach(row; zip(indexes, source))
 	{
 		foreach(col; row) {
 			write(col, " ");
 		}
 		writeln;
 	}
 }

 void printIndexedArray2(T, Range)(T[] source, Range indexes)
 {
 	writef("%(%(%s %)\n%)", zip(indexes, source));
 }

 void main()
 {
 	uint[] data = [17, 30, 48, 140, 10, 01, 126, 138, 140, 3, 501];
 	printIndexedArray1(data, sequence!"n");
 	printIndexedArray2(data, sequence!"n");

 }
 +++

 Looks fairly straightforward. But, the second function causes 
 compilation error:

 std.format.FormatException C:\D\dmd2\windows\bin\..\..\src\phobos\std\format.d(2
 585): Expected '%s' format specifier for type 'Tuple!(uint, 
 uint)'

 Can you help me with that?
You can turn the tuples into ranges with `only`: writef("%(%(%s %)\n%)", zip(indexes, source).map!(t => only(t.expand)));
Oct 08 2014
next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 10/08/2014 02:34 PM, anonymous wrote:

 You can turn the tuples into ranges with `only`:

 writef("%(%(%s %)\n%)", zip(indexes, source).map!(t =>
 only(t.expand)));
I haven't measured the performance but there is also the following automatic expansion of tuple members as slice elements: ... zip(indexes, source).map!(t => [ t ])); Probably the same thing... Ali
Oct 08 2014
prev sibling next sibling parent "antropod" <antropod gmail.com> writes:
On Wednesday, 8 October 2014 at 21:34:54 UTC, anonymous wrote:
 You can turn the tuples into ranges with `only`:

 writef("%(%(%s %)\n%)", zip(indexes, source).map!(t =>
 only(t.expand)));
That works for me, thanks. By the way my compiler is DMD 2.066.0
Oct 08 2014
prev sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
anonymous:

 You can turn the tuples into ranges with `only`:

 writef("%(%(%s %)\n%)", zip(indexes, source).map!(t => 
 only(t.expand)));
This is a nice idea. Expand can probably be replaced by a []. I presume this works only if the types inside the tuple are the same. Bye, bearophile
Oct 08 2014
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Wednesday, 8 October 2014 at 23:28:34 UTC, bearophile wrote:
 anonymous:

 You can turn the tuples into ranges with `only`:

 writef("%(%(%s %)\n%)", zip(indexes, source).map!(t => 
 only(t.expand)));
This is a nice idea. Expand can probably be replaced by a []. I presume this works only if the types inside the tuple are the same.
Expand creates "returns" a TypeTuple though, so it's arguably "free". "[]" allocates a dynamic array, so is costly. On the flip side, "only" is *entirelly* by value, and carries all its arguments. If the tuple is big, then the range can become quite big.
Oct 13 2014
parent "Sag Academy" <sagacademyjaipur gmail.com> writes:
On Monday, 13 October 2014 at 09:20:27 UTC, monarch_dodra wrote:
 On Wednesday, 8 October 2014 at 23:28:34 UTC, bearophile wrote:
 anonymous:

 You can turn the tuples into ranges with `only`:

 writef("%(%(%s %)\n%)", zip(indexes, source).map!(t => 
 only(t.expand)));
This is a nice idea. Expand can probably be replaced by a []. I presume this works only if the types inside the tuple are the same.
Expand creates "returns" a TypeTuple though, so it's arguably "free". "[]" allocates a dynamic array, so is costly. On the flip side, "only" is *entirelly* by value, and carries all its arguments. If the tuple is big, then the range can become quite big.
 you are right man.
Oct 13 2014