Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
July 02, 2012 foreach and retro | ||||
---|---|---|---|---|
| ||||
Hello all, A problem with the retro function from std.range -- although it apparently operates on a bidirectional range, it fails when used with foreach requesting both value and index. Running this code: //////////////////////////////////////////////// import std.range, std.stdio; void main() { double[] a = [ 0, 1, 2, 3, 4, 5 ]; foreach(i, x; retro(a)) writeln(i, "\t", x); } //////////////////////////////////////////////// ... results in an error: "cannot infer argument types". Is there any reason why this should be so, or is it (as it seems to me) just a bug? Thanks & best wishes, -- Joe |
July 02, 2012 Re: foreach and retro | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joseph Rushton Wakeling | On 07/02/2012 05:36 PM, Joseph Rushton Wakeling wrote:
> Hello all,
>
> A problem with the retro function from std.range -- although it
> apparently operates on a bidirectional range, it fails when used with
> foreach requesting both value and index. Running this code:
>
> ////////////////////////////////////////////////
> import std.range, std.stdio;
>
> void main()
> {
> double[] a = [ 0, 1, 2, 3, 4, 5 ];
>
> foreach(i, x; retro(a))
> writeln(i, "\t", x);
> }
> ////////////////////////////////////////////////
>
> ... results in an error: "cannot infer argument types".
>
> Is there any reason why this should be so, or is it (as it seems to me)
> just a bug?
>
> Thanks & best wishes,
>
> -- Joe
What would be your expected output?
|
July 02, 2012 Re: foreach and retro | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | > What would be your expected output?
From the inner to the outer expression:
First the range is reversed and then the elements of this range
are enumerated.
|
July 02, 2012 Re: foreach and retro | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joseph Rushton Wakeling | Joseph Rushton Wakeling: > double[] a = [ 0, 1, 2, 3, 4, 5 ]; > > foreach(i, x; retro(a)) > writeln(i, "\t", x); It's not a bug, it's caused by how ranges like retro work. retro yields a single item. In D you can't overload on return values, so foreach can't try to call a second retro.front overload that yields an (index,item) tuple (that later foreach is able to unpack on the fly) instead of the retro.front that just yields the item. To solve that problem this is what I have suggested to add to Phobos: http://d.puremagic.com/issues/show_bug.cgi?id=5550 Bye, bearophile |
July 02, 2012 Re: foreach and retro | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 02/07/12 17:48, Timon Gehr wrote:
> What would be your expected output?
I'd expect to see
0 5
1 4
2 3
3 2
4 1
5 0
i.e. as if I was foreach-ing over an array with the same values in inverted order.
|
July 02, 2012 Re: foreach and retro | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joseph Rushton Wakeling | On Monday, 2 July 2012 at 16:49:06 UTC, Joseph Rushton Wakeling wrote:
> On 02/07/12 17:48, Timon Gehr wrote:
>> What would be your expected output?
>
> I'd expect to see
>
> 0 5
> 1 4
> 2 3
> 3 2
> 4 1
> 5 0
>
> i.e. as if I was foreach-ing over an array with the same values in inverted order.
Use the .array() property:
auto Range(alias func, Args...)(Args args) {
return func(args).array();
}
void main() {}
double[] ad = [ 0, 1, 2, 3, 4, 5 ];
foreach(index, x; Range!(retro)(ad)) {
writeln(index, "\t", x);
}
}
|
July 02, 2012 Re: foreach and retro | ||||
---|---|---|---|---|
| ||||
D does not provide index for the range iteration. Instead, you can create 'zipped' range. void main() { auto intr = sequence!"n"(); // 0, 1, 2, ... double[] a = [ 0, 1, 2, 3, 4, 5 ]; foreach(i, x; zip(intr, retro(a))) writeln(i, "\t", x); } zip(intr, retro(a)) is a range of Tuple!(size_t, double), and foreach automatically expand the tow fields of zip front into i and x like follows. foreach(__e; zip(intr, retro(a))) { auto i = __elem[0], x = __elem[1]; // inserted by the compiler writeln(i, "\t", x); } After all, you can get 'index' for range iteration. Kenji Hara 2012/7/3 Joseph Rushton Wakeling <joseph.wakeling@webdrake.net>: > On 02/07/12 17:48, Timon Gehr wrote: >> >> What would be your expected output? > > > I'd expect to see > > 0 5 > 1 4 > 2 3 > 3 2 > 4 1 > 5 0 > > i.e. as if I was foreach-ing over an array with the same values in inverted order. |
July 02, 2012 Re: foreach and retro | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | "bearophile" , dans le message (digitalmars.D:171013), a écrit : > It's not a bug, it's caused by how ranges like retro work. retro yields a single item. In D you can't overload on return values, But you can overload OpApply. -- Christophe |
July 04, 2012 Re: foreach and retro | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 02/07/12 18:43, bearophile wrote: > It's not a bug, it's caused by how ranges like retro work. retro yields a single > item. In D you can't overload on return values, so foreach can't try to call a > second retro.front overload that yields an (index,item) tuple (that later > foreach is able to unpack on the fly) instead of the retro.front that just > yields the item. Ahh, OK. Clear, just a little surprising. > To solve that problem this is what I have suggested to add to Phobos: > http://d.puremagic.com/issues/show_bug.cgi?id=5550 Looks like a nice idea! The reason I was interested was because of a case where a foreach_reverse was called for across an array, but where it was useful to flip the indices as well. |
July 04, 2012 Re: foreach and retro | ||||
---|---|---|---|---|
| ||||
On 02/07/12 18:57, kenji hara wrote:
> D does not provide index for the range iteration.
> Instead, you can create 'zipped' range.
Oh, cool. That's a nice feature that I can think of other uses for ... :-)
|
Copyright © 1999-2021 by the D Language Foundation