www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Indexed foreach on struct?

reply Matt Soucy <msoucy csh.rit.edu> writes:
So I was messing around with some code I've been writing recently, and I 
wanted to use a foreach on a struct as if it were an associative array. 
The problem is, I can't find any information on how to do that.
I can't use something like "alias this", because the class I'm writing 
acts as a wrapper that lets me use string offsets for something that's 
not string-indexed by default, so there's nothing to alias it TO.
I don't see any sort of opApply or similar to do this, and the foreach 
section of dlang.org doesn't help. Is there a way to do it, or do I need 
to do a workaround?
Thank you,
-Matt Soucy
Jan 23 2012
next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Mon, Jan 23, 2012 at 03:32:07PM -0500, Matt Soucy wrote:
 So I was messing around with some code I've been writing recently,
 and I wanted to use a foreach on a struct as if it were an
 associative array. The problem is, I can't find any information on
 how to do that.

 I don't see any sort of opApply or similar to do this, and the
 foreach section of dlang.org doesn't help. Is there a way to do it,
 or do I need to do a workaround?

You can use opApply. Sample test program: struct Test { int opApply(int delegate(ref int) dg) { auto ret = 0; for (auto i=0; ret==0 && i<5; i++) { ret = dg(i); } return ret; } } import std.stdio; void main() { Test t; foreach (n; t) { writeln(n); } } Program prints: 0 1 2 3 4 Hope that helps. T -- If you look at a thing nine hundred and ninety-nine times, you are perfectly safe; if you look at it the thousandth time, you are in frightful danger of seeing it for the first time. -- G. K. Chesterton
Jan 23 2012
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 01/23/2012 01:16 PM, H. S. Teoh wrote:
 On Mon, Jan 23, 2012 at 03:32:07PM -0500, Matt Soucy wrote:
 So I was messing around with some code I've been writing recently,
 and I wanted to use a foreach on a struct as if it were an
 associative array. The problem is, I can't find any information on
 how to do that.

 I don't see any sort of opApply or similar to do this, and the
 foreach section of dlang.org doesn't help. Is there a way to do it,
 or do I need to do a workaround?

You can use opApply.

And potentially more than one overload to match the foreach loop variables.
 Sample test program:

 	struct Test {
 		int opApply(int delegate(ref int) dg) {
 			auto ret = 0;
 			for (auto i=0; ret==0&&  i<5; i++) {
 				ret = dg(i);

Add: if (ret) { break; } ret is non-zero if the foreach body contains a break statement.
 			}
 			return ret;
 		}
 	}

 	import std.stdio;
 	void main() {
 		Test t;

 		foreach (n; t) {
 			writeln(n);
 		}
 	}

 Program prints:

 	0
 	1
 	2
 	3
 	4

 Hope that helps.


 T

Ali
Jan 23 2012
prev sibling next sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 01/23/2012 12:32 PM, Matt Soucy wrote:
 So I was messing around with some code I've been writing recently, and I
 wanted to use a foreach on a struct as if it were an associative array.

bearophile and I had replied to your earlier post. Ali
Jan 23 2012
parent reply Matt Soucy <msoucy csh.rit.edu> writes:
On 01/23/2012 04:28 PM, Ali Çehreli wrote:
 On 01/23/2012 12:32 PM, Matt Soucy wrote:
 So I was messing around with some code I've been writing recently, and I
 wanted to use a foreach on a struct as if it were an associative array.

bearophile and I had replied to your earlier post. Ali

showing up at http://www.digitalmars.com/d/archives/digitalmars/D/learn/index.html or in Thunderbird, so I thought there had been some sort of problem. I had to repair the folder in Thunderbird in order for the posts to show up. I'll make sure this doesn't happen again. But between replies to both posts, I have enough information to do what I need to. So thank you. -Matt
Jan 23 2012
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 01/23/2012 03:27 PM, Matt Soucy wrote:
 On 01/23/2012 04:28 PM, Ali Çehreli wrote:
 On 01/23/2012 12:32 PM, Matt Soucy wrote:
 So I was messing around with some code I've been writing recently, 



 wanted to use a foreach on a struct as if it were an associative array.

bearophile and I had replied to your earlier post. Ali

showing up at http://www.digitalmars.com/d/archives/digitalmars/D/learn/index.html or in Thunderbird, so I thought there had been some sort of problem. I had to repair the folder in Thunderbird in order for the posts to show up. I'll make sure this doesn't happen again.

No problem at all. :) Just making sure that posts don't get lost.
 But between replies to both posts, I have enough information to do what
 I need to. So thank you.
 -Matt

Great! :) Ali
Jan 23 2012
prev sibling next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Mon, Jan 23, 2012 at 01:16:29PM -0800, H. S. Teoh wrote:
 On Mon, Jan 23, 2012 at 03:32:07PM -0500, Matt Soucy wrote:
 So I was messing around with some code I've been writing recently,
 and I wanted to use a foreach on a struct as if it were an
 associative array. The problem is, I can't find any information on
 how to do that.


Oops, missed the part about associative arrays. For that, you can simply add more arguments to the delegate, for example: struct Test { int opApply(int delegate(ref int, ref int) dg) { auto ret = 0; for (auto i=0; ret==0 && i<5; i++) { auto j = i+10; ret = dg(i, j); } return ret; } } import std.stdio; void main() { Test t; foreach (n, m; t) { writeln(n, " ", m); } } T -- "I suspect the best way to deal with procrastination is to put off the procrastination itself until later. I've been meaning to try this, but haven't gotten around to it yet. " -- swr
Jan 23 2012
prev sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Mon, Jan 23, 2012 at 01:26:44PM -0800, Ali ehreli wrote:
 On 01/23/2012 01:16 PM, H. S. Teoh wrote:

 	struct Test {
 		int opApply(int delegate(ref int) dg) {
 			auto ret = 0;
 			for (auto i=0; ret==0&&  i<5; i++) {
 				ret = dg(i);

Add: if (ret) { break; } ret is non-zero if the foreach body contains a break statement.

Actually I already put that into the loop condition. But yes, the return value needs to be checked. T -- If Java had true garbage collection, most programs would delete themselves upon execution. -- Robert Sewell
Jan 23 2012