Лучший способ удалить предметы из коллекции
Как лучше всего подойти к удалению элементов 9X_collections из коллекции на C#, если элемент известен, но 9X_c# не индексирован. Это один из способов сделать 9X_c# это, но в лучшем случае он кажется неэлегантным.
//Remove the existing role assignment for the user. int cnt = 0; int assToDelete = 0; foreach (SPRoleAssignment spAssignment in workspace.RoleAssignments) { if (spAssignment.Member.Name == shortName) { assToDelete = cnt; } cnt++; } workspace.RoleAssignments.Remove(assToDelete);
Что 9X_csharp мне действительно хотелось бы сделать, так 9X_collection это найти элемент, который нужно удалить, по 9X_c-sharp свойству (в данном случае по имени) без 9X_c# перебора всей коллекции и использования 9X_c-sharp двух дополнительных переменных.
- Любите имена переменных. О ...
Ответ #1
Ответ на вопрос: Лучший способ удалить предметы из коллекции
Если RoleAssignments - это List
, вы можете использовать 9X_java-collections-api следующий код.
workSpace.RoleAssignments.RemoveAll(x =>x.Member.Name == shortName);
- AFAIK, это удаление на месте.<p><span class ...
Ответ #2
Ответ на вопрос: Лучший способ удалить предметы из коллекции
Если вы хотите получить доступ к членам 9X_visual-c# коллекции по одному из их свойств, вы можете 9X_.cs-file рассмотреть возможность использования вместо 9X_c#-language них Dictionary
или KeyedCollection
. Таким образом, вам не придется 9X_c#-language искать предмет, который вы ищете.
В противном 9X_c-sharp случае вы могли бы хотя бы так:
foreach (SPRoleAssignment spAssignment in workspace.RoleAssignments) { if (spAssignment.Member.Name == shortName) { workspace.RoleAssignments.Remove(spAssignment); break; } }
- Это вызовет исключение, пото ...
Ответ #3
Ответ на вопрос: Лучший способ удалить предметы из коллекции
@smaclell спросил, почему обратная итерация 9X_collections более эффективна, в комментарии к @ sambo99.
Иногда это 9X_collections более эффективно. Предположим, у вас есть 9X_java-collections-api список людей, и вы хотите удалить или отфильтровать 9X_c#-language всех клиентов с кредитным рейтингом <1000;
У 9X_visual-c# нас есть следующие данные
"Bob" 999 "Mary" 999 "Ted" 1000
Если бы мы пошли 9X_csharp дальше, у нас вскоре были бы проблемы
for( int idx = 0; idx < list.Count ; idx++ ) { if( list[idx].Rating < 1000 ) { list.RemoveAt(idx); // whoops! } }
При 9X_c#.net idx = 0 мы удаляем Bob
, который затем сдвигает 9X_collections все оставшиеся элементы влево. В следующий 9X_c#-language раз через цикл idx = 1, но list [1] теперь 9X_.cs-file Ted
вместо Mary
. В итоге мы по ошибке пропускаем 9X_.cs-file Mary
. Мы могли бы использовать цикл while и 9X_.cs-file ввести больше переменных.
Или мы просто выполняем 9X_csharp обратную итерацию:
for (int idx = list.Count-1; idx >= 0; idx--) { if (list[idx].Rating < 1000) { list.RemoveAt(idx); } }
Все индексы слева от удаленного 9X_csharp элемента остаются прежними, поэтому вы не 9X_collections пропустите ни одного элемента.
Тот же принцип 9X_c#.net применяется, если вам дан список индексов, которые 9X_c#-language нужно удалить из массива. Чтобы не усложнять 9X_c-sharp задачу, вам нужно отсортировать список, а 9X_collection затем удалить элементы от самого высокого 9X_.cs-file индекса до самого низкого.
Теперь вы можете 9X_.cs-file просто использовать Linq и прямо заявлять 9X_c-sharp о своих действиях.
list.RemoveAll(o => o.Rating < 1000);
В этом случае удаление 9X_c-sharp одного элемента не более эффективно итерация 9X_c# вперед или назад. Вы также можете использовать 9X_c#.net для этого Linq.
int removeIndex = list.FindIndex(o => o.Name == "Ted"); if( removeIndex != -1 ) { list.RemoveAt(removeIndex); }
- Для простого List <t>, если вам нужно удалить более 1 элемента, обратный цикл for ВСЕГДА является наиболее эффективным способом сделать это. Это, безусловно, более эффективно, чем копирование данных в список listToRemove. Готов поспорить, реализаци ...
Ответ #4
Ответ на вопрос: Лучший способ удалить предметы из коллекции
Если это ICollection
, тогда у вас не будет метода RemoveAll
. Вот 9X_csharp метод расширения, который сделает это:
public static void RemoveAll(this ICollection source, Func predicate) { if (source == null) throw new ArgumentNullException("source", "source is null."); if (predicate == null) throw new ArgumentNullException("predicate", "predicate is null."); source.Where(predicate).ToList().ForEach(e => source.Remove(e)); }
На 9X_visual-c# основе: http://phejndorf.wordpress.com/2011/03/09/a-removeall-extension-for-the-collection-class/
Ответ #5
Ответ на вопрос: Лучший способ удалить предметы из коллекции
Для простой структуры списка наиболее эффективным 9X_c# способом является использование реализации 9X_collection Predicate RemoveAll.
Например.
workSpace.RoleAssignments.RemoveAll(x =>x.Member.Name == shortName);
Причины:
- Метод Predicate / Linq RemoveAll реализован в List и имеет доступ к внутреннему массиву, хранящему фактические данные. Он сдвинет данные и изменит размер внутреннего массива.
- Реализация метода RemoveAt довольно медленная и будет копировать весь базовый массив данных в новый массив. Это означает, что обратная итерация бесполезна для List
Если 9X_csharp вы застряли в реализации этого в эпоху до 9X_c#.net C# 3.0. У вас есть 2 варианта.
- Легко обслуживаемый вариант. Скопируйте все совпадающие элементы в новый список и поменяйте местами базовый список.
Например.
List list2 = new List() ; foreach (int i in GetList()) { if (!(i % 2 == 0)) { list2.Add(i); } } list2 = list2;
Или
- Сложный, немного более быстрый вариант, который включает в себя смещение всех данных в списке вниз, когда они не совпадают, а затем изменение размера массива.
Если 9X_c#-language вы действительно часто удаляете данные из 9X_c#-language списка, возможно, лучше подойдет другая 9X_java-collections-api структура, например HashTable (.net 1.1), Dictionary (.net 9X_.cs-file 2.0) или HashSet (.net 3.5). для этого.
Ответ #6
Ответ на вопрос: Лучший способ удалить предметы из коллекции
К какому типу относится коллекция? Если 9X_c#-language это List, вы можете использовать полезный 9X_java-collections-api "RemoveAll":
int cnt = workspace.RoleAssignments .RemoveAll(spa => spa.Member.Name == shortName)
(Это работает в .NET 2.0. Конечно, если 9X_.cs-file у вас нет более новой версии компилятора, вам 9X_java-collections-api придется вместо этого использовать "delegate 9X_c-sharp (SPRoleAssignment spa) {return spa.Member.Name 9X_visual-c# == shortName;}" красивого синтаксиса лямбда.)
Другой 9X_visual-c# подход, если это не список, но все же ICollection:
var toRemove = workspace.RoleAssignments .FirstOrDefault(spa => spa.Member.Name == shortName) if (toRemove != null) workspace.RoleAssignments.Remove(toRemove);
Для 9X_c#.net этого требуются методы расширения Enumerable. (Вы 9X_c#.net можете скопировать Mono, если вы застряли 9X_visual-c# на .NET 2.0). Если это какая-то настраиваемая 9X_c#-language коллекция, которая не может принимать элемент, но 9X_c# ДОЛЖНА принимать индекс, некоторые другие 9X_c-sharp методы Enumerable, такие как Select, передают 9X_csharp целочисленный индекс за вас.
Ответ #7
Ответ на вопрос: Лучший способ удалить предметы из коллекции
Вот довольно хороший способ сделать это
http://support.microsoft.com/kb/555972
System.Collections.ArrayList arr = new System.Collections.ArrayList(); arr.Add("1"); arr.Add("2"); arr.Add("3"); /*This throws an exception foreach (string s in arr) { arr.Remove(s); } */ //where as this works correctly Console.WriteLine(arr.Count); foreach (string s in new System.Collections.ArrayList(arr)) { arr.Remove(s); } Console.WriteLine(arr.Count); Console.ReadKey();
9X_java-collections-api
Ответ #8
Ответ на вопрос: Лучший способ удалить предметы из коллекции
Это мое общее решение
public static IEnumerable Remove(this IEnumerable items, Func match) { var list = items.ToList(); for (int idx = 0; idx < list.Count(); idx++) { if (match(list[idx])) { list.RemoveAt(idx); idx--; // the list is 1 item shorter } } return list.AsEnumerable(); }
Было бы намного проще, если 9X_collections бы методы расширения поддерживали передачу 9X_visual-c# по ссылке! использование:
var result = string[]{"mike", "john", "ali"} result = result.Remove(x => x.Username == "mike").ToArray(); Assert.IsTrue(result.Length == 2);
РЕДАКТИРОВАТЬ: гарантирует, что 9X_c-sharp цикл списка остается действительным даже 9X_visual-c# при удалении элементов путем уменьшения 9X_c# индекса (idx).
-
8
-
7
-
9
-
12
-
10
-
24
-
7
-
9
-
6
-
5
-
5
-
4
-
10
-
7
-
6
-
8
-
3
-
8
-
6
-
4
-
4
-
8
-
10
-
2
-
4
-
3
-
5
-
4
-
6
-
9
-
5
-
5
-
9
-
5
-
4
-
5
-
5
-
5
-
4
-
6
-
7
-
7
-
5
-
5
-
3
-
3
-
5
-
4
-
5
-
8