www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - extended foreach?

reply Mandel <mandel mailinator.com> writes:
Hi,

I like to know if this feature request is even feasible
and what others think of it, of course.

class Foo {
   int opApply(int delegate(ref Type [, ...]) dg, float f, char[] s) {
       /*...*/
   }
}

float f = 1.5;
char[] s = "abc";
foreach(x; xs; foo; f, s)
{

}

The idea is to pass additional values from foreach to opApply.
Would be great to filter values in opApply for example.
(or even chaining foreach in opApply...)
May 31 2007
parent reply Daniel Keep <daniel.keep.lists gmail.com> writes:
Mandel wrote:
 Hi,
 
 I like to know if this feature request is even feasible
 and what others think of it, of course.
 
 class Foo {
    int opApply(int delegate(ref Type [, ...]) dg, float f, char[] s) {
        /*...*/
    }
 }
 
 float f = 1.5;
 char[] s = "abc";
 foreach(x; xs; foo; f, s)
 {
 
 }
 
 The idea is to pass additional values from foreach to opApply.
 Would be great to filter values in opApply for example.
 (or even chaining foreach in opApply...)

Usually, this is done by having a member function that returns a struct (or class instance) that has an opApply on it. For instace: class Foo { struct FooIter { float f; char[] s; int opApply(int delegate(ref Type [, ...]) dg) { /* ... */ } } FooIter myIter(float f, char[] s) { return FooIter(f,s); } } float f = 1.5; char[] s = "abc"; foreach(x, xs; foo.myIter(f, s)) { } -- int getRandomNumber() { return 4; // chosen by fair dice roll. // guaranteed to be random. } http://xkcd.com/ v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
May 31 2007
parent mandel <mandel mailinator.com> writes:
That's actually the way I do it at the moment.
But it is clumsy to expose an interator class/struct for that.
Calling opApply with additional arguments
would result in a more native and simpler solution.
There would be also only stack allocated memory (not sure, but I give that
argument a shot :P).
It's also seems to be an artificial limitation. - Does someone know if I'm
right here?

class Foo
{
  int opApply(int delegate(ref Type [, ...]) dg, uint arg = 0)
  {
	int ret = 0;
	foreach(V item; items)
	{
		if(item.size <= size) break; //use of an additional argument for filtering
		if(uint ret = dg(item)) break;
	}
	return ret;
  }
}



Daniel Keep Wrote:

 
 
 Mandel wrote:
 Hi,
 
 I like to know if this feature request is even feasible
 and what others think of it, of course.
 
 class Foo {
    int opApply(int delegate(ref Type [, ...]) dg, float f, char[] s) {
        /*...*/
    }
 }
 
 float f = 1.5;
 char[] s = "abc";
 foreach(x; xs; foo; f, s)
 {
 
 }
 
 The idea is to pass additional values from foreach to opApply.
 Would be great to filter values in opApply for example.
 (or even chaining foreach in opApply...)

Usually, this is done by having a member function that returns a struct (or class instance) that has an opApply on it. For instace: class Foo { struct FooIter { float f; char[] s; int opApply(int delegate(ref Type [, ...]) dg) { /* ... */ } } FooIter myIter(float f, char[] s) { return FooIter(f,s); } } float f = 1.5; char[] s = "abc"; foreach(x, xs; foo.myIter(f, s)) { } -- int getRandomNumber() { return 4; // chosen by fair dice roll. // guaranteed to be random. } http://xkcd.com/ v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/

Jun 20 2007