La colección fue modificada; la operación de enumeración no puede ejecutarse en ArrayList [duplicar]
Esta pregunta ya tiene una respuesta aquí:
Estoy tratando de eliminar un elemento de un ArrayList
y obtengo esta excepción:Collection was modified; enumeration operation may not execute.
¿Alguna idea?
9 answers
Usted está quitando el elemento durante un foreach
, sí? Simplemente, no se puede. Hay algunas opciones comunes aquí:
- use
List<T>
yRemoveAll
con un predicado -
Iterar hacia atrás por índice, eliminando elementos coincidentes
for(int i = list.Count - 1; i >= 0; i--) { if({some test}) list.RemoveAt(i); }
-
Use
foreach
, y ponga los elementos coincidentes en una segunda lista; ahora enumere la segunda lista y elimine esos elementos de la primera (si ve lo que quiero decir)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-07 22:34:22
Aquí hay un ejemplo (lo siento por cualquier error tipográfico)
var itemsToRemove = new ArrayList(); // should use generic List if you can
foreach (var item in originalArrayList) {
if (...) {
itemsToRemove.Add(item);
}
}
foreach (var item in itemsToRemove) {
originalArrayList.Remove(item);
}
O si está usando 3.5, Linq hace que el primer bit sea más fácil:
itemsToRemove = originalArrayList
.Where(item => ...)
.ToArray();
foreach (var item in itemsToRemove) {
originalArrayList.Remove(item);
}
Reemplazar "..."con su condición que determina si el elemento debe ser eliminado.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-07 22:46:47
Una forma es agregar el elemento(s) que se eliminará (n) a una nueva lista. Luego ir a través y eliminar esos elementos.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-07 22:35:41
Me gusta iterar hacia atrás usando un bucle for
, pero esto puede ser tedioso en comparación con foreach
. Una solución que me gusta es crear un enumerador que recorre la lista hacia atrás. Puede implementar esto como un método de extensión en ArrayList
o List<T>
. La implementación para ArrayList
es la siguiente.
public static IEnumerable GetRemoveSafeEnumerator(this ArrayList list)
{
for (int i = list.Count - 1; i >= 0; i--)
{
// Reset the value of i if it is invalid.
// This occurs when more than one item
// is removed from the list during the enumeration.
if (i >= list.Count)
{
if (list.Count == 0)
yield break;
i = list.Count - 1;
}
yield return list[i];
}
}
La implementación para List<T>
es similar.
public static IEnumerable<T> GetRemoveSafeEnumerator<T>(this List<T> list)
{
for (int i = list.Count - 1; i >= 0; i--)
{
// Reset the value of i if it is invalid.
// This occurs when more than one item
// is removed from the list during the enumeration.
if (i >= list.Count)
{
if (list.Count == 0)
yield break;
i = list.Count - 1;
}
yield return list[i];
}
}
El siguiente ejemplo usa el enumerador para eliminar todos los enteros pares de un ArrayList
.
ArrayList list = new ArrayList() {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
foreach (int item in list.GetRemoveSafeEnumerator())
{
if (item % 2 == 0)
list.Remove(item);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-26 15:16:40
No modifique la lista dentro de un bucle que itere a través de la lista.
En su lugar, use un for()
o while()
con un índice, yendo hacia atrás a través de la lista. (Esto le permitirá eliminar cosas sin obtener un índice no válido.)
var foo = new List<Bar>();
for(int i = foo.Count-1; i >= 0; --i)
{
var item = foo[i];
// do something with item
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-17 16:17:50
¿Me estoy perdiendo algo? Que alguien me corrija si me equivoco.
list.RemoveAll(s => s.Name == "Fred");
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-07 20:15:15
En lugar de foreach(), use un bucle for() con un índice numérico.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-07 22:35:21
Estoy de acuerdo con varios de los puntos que he leído en este post y los he incorporado en mi solución para resolver exactamente el mismo problema que la publicación original.
Dicho esto, los comentarios que aprecié son:
"a menos que esté usando. NET 1.0 o 1.1, use
List<T>
en lugar deArrayList
. ""Además, agregue el (los) elemento (s) que se eliminará (n) a una nueva lista. Luego ir a través y eliminar esos elementos." .. en mi caso acabo de crear una nueva Lista y la rellené con el valores de datos válidos.
Por ejemplo
private List<string> managedLocationIDList = new List<string>();
string managedLocationIDs = ";1321;1235;;" // user input, should be semicolon seperated list of values
managedLocationIDList.AddRange(managedLocationIDs.Split(new char[] { ';' }));
List<string> checkLocationIDs = new List<string>();
// Remove any duplicate ID's and cleanup the string holding the list if ID's
Functions helper = new Functions();
checkLocationIDs = helper.ParseList(managedLocationIDList);
...
public List<string> ParseList(List<string> checkList)
{
List<string> verifiedList = new List<string>();
foreach (string listItem in checkList)
if (!verifiedList.Contains(listItem.Trim()) && listItem != string.Empty)
verifiedList.Add(listItem.Trim());
verifiedList.Sort();
return verifiedList;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-29 15:34:39
Usando ArrayList
también puedes probar así
ArrayList arraylist = ... // myobject data list
ArrayList temp = (ArrayList)arraylist.Clone();
foreach (var item in temp)
{
if (...)
arraylist.Remove(item);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-24 07:19:59