473,503 Members | 2,173 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

How do you modify an array while iterating through it?

I ran into this problem today: I got an array with Account objects. I need
to iterate through this array to supplement the accounts in the array with
more data. But the compiler complains when I try to modify the objects in
the array while iterating through it. I marked the bugs in this code:

// Loop through all previously added accounts
foreach(Account a in a1) // a1 is an ArrayList
{
// If name and context is the same
if(a.Name == name && a.Context == context)
{
// Add the amount to the existing account object in the array
a.Amount += amount; // BUG!
break;
}
else
{
// Add a new account object to the array
Account newAccount = new Account(name, ns, context, amount);
a1.Add(newAccount); // BUG!
}
}

There is an outer loop where name, context and amount are found. Hope I
provided enough info. What is the right way of doing this?

Gustaf

Nov 15 '05 #1
6 6030
Gustaf Liljegren <gu**************@bredband.net> wrote:
I ran into this problem today: I got an array with Account objects. I need
to iterate through this array to supplement the accounts in the array with
more data. But the compiler complains when I try to modify the objects in
the array while iterating through it. I marked the bugs in this code:

// Loop through all previously added accounts
foreach(Account a in a1) // a1 is an ArrayList
{
// If name and context is the same
if(a.Name == name && a.Context == context)
{
// Add the amount to the existing account object in the array
a.Amount += amount; // BUG!
break;
}
else
{
// Add a new account object to the array
Account newAccount = new Account(name, ns, context, amount);
a1.Add(newAccount); // BUG!
}
}

There is an outer loop where name, context and amount are found. Hope I
provided enough info. What is the right way of doing this?


You should be able to change the account itself - the first one
shouldn't be a problem, in other words (unless it's a value type?) -
but the second one is changing the list itself, which you can't do
without it throwing an exception. However, I'm surprised if you get a
*compiler* exception rather than a runtime exception.

Could you produce a short but complete example program which
demonstrates the problem?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #2
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote:
You should be able to change the account itself - the first one
shouldn't be a problem, in other words (unless it's a value type?) -
You're right. This is in fact no problem.
but the second one is changing the list itself, which you can't do
without it throwing an exception. However, I'm surprised if you get a
*compiler* exception rather than a runtime exception.


Rigth again. I learned to separate them now.

So, the problem remaining is how to add another Account within that loop.
The logic is:

1. See if the account already exists in the array.
2. If it does, add a new amount to the old one. If not, create a new account
in the array.

I'll see if I can come up with a simple example to work on.

Gustaf

Nov 15 '05 #3
Gustaf Liljegren <gu**************@bredband.net> wrote:

<snip>
So, the problem remaining is how to add another Account within that loop.
The logic is:

1. See if the account already exists in the array.
2. If it does, add a new amount to the old one. If not, create a new account
in the array.

I'll see if I can come up with a simple example to work on.


You can't change a list while you're iterating through it. One common
solution is to build up another list containing the items you *want* to
add to the list, and then add all of them after you've finished
iterating. (You could use ArrayList.AddRange for that.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #4

"Gustaf Liljegren" <gu**************@bredband.net> wrote in message
news:et**************@TK2MSFTNGP10.phx.gbl...
So, the problem remaining is how to add another Account within that loop.
The logic is:

1. See if the account already exists in the array.
2. If it does, add a new amount to the old one. If not, create a new account in the array.


You could change the foreach-statement into a for-loop (going backwards).

Or even better. Not use an ArrayList, but a HashTable for the lookup.

Best Regards

- Michael S
Nov 15 '05 #5
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote:
You can't change a list while you're iterating through it. One common
solution is to build up another list containing the items you *want* to
add to the list, and then add all of them after you've finished
iterating. (You could use ArrayList.AddRange for that.)


Thanks for all your help. I see that I have not given a good enough
description. It's a grouping problem. The input data is a list of accounts
(identified by name) where some accounts occurs more than once. I want the
accounts grouped so that the amounts are summed up. For example, this input
data

Account 1: 2.50
Account 2: 7.00
Account 1: 1.50
Account 3: 9.00
Account 2: 3.50
Account 2: 6.00
Account 3: 3.50
Account 1: 6.50

shall result in these groups (each in an Account object):

Account 1: 10.5
Account 2: 16.5
Account 3: 12.5

My way of doing this is looping through the input data, account by account.
If the account has already been found, I just add the amount from the
current account object. If not, I add the whole object to the array. But it
won't work, since I can't add items to the array while iterating through it.

Maybe I need an Accounts collection class with methods like AccountExists(),
AddAccount() and UpdateAmount().

Gustaf

Nov 15 '05 #6
Gustaf Liljegren <gu**************@bredband.net> wrote:
You can't change a list while you're iterating through it. One common
solution is to build up another list containing the items you *want* to
add to the list, and then add all of them after you've finished
iterating. (You could use ArrayList.AddRange for that.)


Thanks for all your help. I see that I have not given a good enough
description. It's a grouping problem. The input data is a list of accounts
(identified by name) where some accounts occurs more than once. I want the
accounts grouped so that the amounts are summed up. For example, this input
data

Account 1: 2.50
Account 2: 7.00
Account 1: 1.50
Account 3: 9.00
Account 2: 3.50
Account 2: 6.00
Account 3: 3.50
Account 1: 6.50

shall result in these groups (each in an Account object):

Account 1: 10.5
Account 2: 16.5
Account 3: 12.5

My way of doing this is looping through the input data, account by account.
If the account has already been found, I just add the amount from the
current account object. If not, I add the whole object to the array. But it
won't work, since I can't add items to the array while iterating through it.


It sounds like you should actually have two different lists (or rather,
a list and a map) - one for the input, and one for the output.
Something like (untested code)

foreach (Account account in inputList)
{
if (outputMap.ContainsKey(account.Name))
{
((Account)outputMap[account.Name]).Amount += account.Amount;
}
else
{
Account copy = new Account (account.Name, account.Amount);
outputMap[copy.Name]=copy;
}
}

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
10664
by: matthurne | last post by:
I need to send just an array to a function which then needs to go through each element in the array. I tried using sizeof(array) / sizeof(array) but since the array is passed into the function,...
5
8776
by: s99999999s2003 | last post by:
hi I wish to pop/del some items out of dictionary while iterating over it. a = { 'a':1, 'b':2 } for k, v in a.iteritems(): if v==2: del a the output say RuntimeError: dictionary changed size...
28
12493
by: Charles Sullivan | last post by:
I'm working on a program which has a "tree" of command line arguments, i.e., myprogram level1 ]] such that there can be more than one level2 argument for each level1 argument and more than one...
32
6471
by: Joe Rattz | last post by:
Hmmm, I wrote the following code. I want an array of bools and I want to intialize them to false. bool bits = new bool; foreach(bool bit in bits) { bit = false; } The compiler complains...
2
1483
by: Yogi21 | last post by:
Hi I have a sorted array containing strings. I am iterating through the array and clearing the contents one by one using "array.BinarySearch" to find each element. So far so good. But the moment I...
9
6290
by: GiantCranesInDublin | last post by:
Hi, I am looking for the best performing solution for modifying and iterating an object graph in JavaScript. I have outlined below a simplified example of the object model and examples of how I...
3
2727
by: pbali | last post by:
Hi, I am using PHP 5.1 and MySQL. I have a result set obtained by executing PDO:: query. I want to create an XML file by using this result set. The XML file will contain column names as XML node...
5
3627
by: Mukesh | last post by:
Hi, I am using framework 2.0. I am writing a foreach loop that will extract single dimensional arrays out of double dimensional array. I am trying writing something like this. string ...
4
9969
by: raylopez99 | last post by:
I would like to know if there's a quick "Linq" way to find the index of an array having a particular value. I can do this the long way by sequential iteration, but would like to know if there's a...
0
7093
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7287
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7467
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5594
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
5022
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3177
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3168
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1521
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
399
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.