Thread overview
Indexed foreach on struct?
Jan 23, 2012
Matt Soucy
Jan 23, 2012
H. S. Teoh
Jan 23, 2012
Ali Çehreli
Jan 23, 2012
H. S. Teoh
Jan 23, 2012
Ali Çehreli
Jan 23, 2012
Matt Soucy
Jan 23, 2012
Ali Çehreli
Jan 23, 2012
H. S. Teoh
January 23, 2012
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
January 23, 2012
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
January 23, 2012
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

January 23, 2012
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
January 23, 2012
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
January 23, 2012
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
January 23, 2012
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
Eek, I'm sorry about that. For some reason, my old sent post wasn't 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
January 23, 2012
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, 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
> Eek, I'm sorry about that. For some reason, my old sent post wasn't
> 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