Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
March 27, 2014 Iterate over an array while mutating it? | ||||
---|---|---|---|---|
| ||||
Hey guys, I want to iterate over an array, while adding new entries, and have those in the iteration loop. See here: https://gist.github.com/AnhNhan/9820226 The problem is that the foreach loop seemingly only iterates over the original array, not minding the newly added entries. Does somebody have a solution or approach for the loop to pick up those new entries? Anh Nhan |
March 27, 2014 Re: Iterate over an array while mutating it? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Anh Nhan | On Thursday, 27 March 2014 at 22:23:41 UTC, Anh Nhan wrote: > I want to iterate over an array, while adding new entries, and have those in the iteration loop. Depending on what you're trying to do, perhaps you would be better off just adding the entries all at once instead of iterating the array? > See here: https://gist.github.com/AnhNhan/9820226 > > The problem is that the foreach loop seemingly only iterates over the original array, not minding the newly added entries. That's correct. foreach caches (which makes it faster) but means that you cannot mutate the range whilst iterating it. > Does somebody have a solution or approach for the loop to pick up those new entries? Your best bet is probably a for loop: for(int i = 0; i < arr.length; i++) { arr ~= element; ... } |
March 27, 2014 Re: Iterate over an array while mutating it? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Anh Nhan | Anh Nhan:
> I want to iterate over an array, while adding new entries, and have those in the iteration loop.
Don't iterate an array with foreach while you mutate it, even if you manage to make it work, the code is not clear.
I suggest to use a C-style for loop with an index and specify in the code exactly what you want to do with the array and the index. The resulting code is clear and safe.
Bye,
bearophile
|
March 27, 2014 Re: Iterate over an array while mutating it? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Infiltrator | On Thursday, 27 March 2014 at 22:26:37 UTC, Infiltrator wrote: > On Thursday, 27 March 2014 at 22:23:41 UTC, Anh Nhan wrote: >> I want to iterate over an array, while adding new entries, and have those in the iteration loop. > > Depending on what you're trying to do, perhaps you would be better off just adding the entries all at once instead of iterating the array? > > >> See here: https://gist.github.com/AnhNhan/9820226 >> >> The problem is that the foreach loop seemingly only iterates over the original array, not minding the newly added entries. > > That's correct. foreach caches (which makes it faster) but means that you cannot mutate the range whilst iterating it. > > >> Does somebody have a solution or approach for the loop to pick up those new entries? > > Your best bet is probably a for loop: > > for(int i = 0; i < arr.length; i++) { arr ~= element; ... } On Thursday, 27 March 2014 at 22:27:18 UTC, bearophile wrote: > Anh Nhan: > >> I want to iterate over an array, while adding new entries, and have those in the iteration loop. > > Don't iterate an array with foreach while you mutate it, even if you manage to make it work, the code is not clear. > I suggest to use a C-style for loop with an index and specify in the code exactly what you want to do with the array and the index. The resulting code is clear and safe. > > Bye, > bearophile Ah, that the foreach caches the entries would make sense. I tried creating iterators Java-style, which did not pick up the new entries, too. It works with for-loops. Thanks for the explanations, they helped a lot. Anh Nhan |
March 28, 2014 Re: Iterate over an array while mutating it? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Anh Nhan | On Thursday, 27 March 2014 at 22:23:41 UTC, Anh Nhan wrote:
> Hey guys,
>
> I want to iterate over an array, while adding new entries, and have those in the iteration loop.
>
> See here: https://gist.github.com/AnhNhan/9820226
>
> The problem is that the foreach loop seemingly only iterates over the original array, not minding the newly added entries.
>
> Does somebody have a solution or approach for the loop to pick up those new entries?
Reallocation will only happen if there isn't sufficient space left in the array. If you know the maximum number of elements in advance, you can reserve the necessary memory:
import std.array;
arr.reserve(arr.length + number_of_new_elements);
|
March 28, 2014 Re: Iterate over an array while mutating it? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Anh Nhan | Anh Nhan:
> Ah, that the foreach caches the entries would make sense.
What does it mean "foreach caches the entries" for you? Foreach does very little. It is light syntax sugar over a normal for loop.
Bye,
bearophile
|
March 28, 2014 Re: Iterate over an array while mutating it? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Anh Nhan | On Thu, 27 Mar 2014 22:23:40 -0000, Anh Nhan <anhnhan@outlook.com> wrote: > Hey guys, > > I want to iterate over an array, while adding new entries, and have those in the iteration loop. > > See here: https://gist.github.com/AnhNhan/9820226 > > The problem is that the foreach loop seemingly only iterates over the original array, not minding the newly added entries. > > Does somebody have a solution or approach for the loop to pick up those new entries? Wrap the array in an adapter class/struct which implements opApply for foreach... import std.stdio; import std.conv; struct ForAdd(T) { T[] data; this(T[] _data) { data = _data; } void opOpAssign(string op : "~")(T rhs) { data ~= rhs; } int opApply(int delegate(ref T) dg) { int result = 0; for (int i = 0; i < data.length; i++) { result = dg(data[i]); if (result) break; } return result; } } int main(string[] args) { string[] test; for(int i = 0; i < 5; i++) test ~= to!string(i); auto adder = ForAdd!string(test); foreach(string item; adder) { writefln("%s", item); if (item == "2") adder ~= "5"; if (item == "4") adder ~= "6"; if (item == "5") adder ~= "7"; } return 0; } R -- Using Opera's revolutionary email client: http://www.opera.com/mail/ |
Copyright © 1999-2021 by the D Language Foundation