Лучший способ удалить предметы из коллекции

Как лучше всего подойти к удалению элементов 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 двух дополнительных переменных.

79
2

  • Любите имена переменных. О ...
8
Общее количество ответов: 8

Ответ #1

Ответ на вопрос: Лучший способ удалить предметы из коллекции

Если RoleAssignments - это List, вы можете использовать 9X_java-collections-api следующий код.

workSpace.RoleAssignments.RemoveAll(x =>x.Member.Name == shortName); 

138
2

  • 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; } } 

29
3

  • Это вызовет исключение, пото ...

Ответ #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); } 

23
1

  • Для простого 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/

12
0

Ответ #5

Ответ на вопрос: Лучший способ удалить предметы из коллекции

Для простой структуры списка наиболее эффективным 9X_c# способом является использование реализации 9X_collection Predicate RemoveAll.

Например.

 workSpace.RoleAssignments.RemoveAll(x =>x.Member.Name == shortName); 

Причины:

  1. Метод Predicate / Linq RemoveAll реализован в List и имеет доступ к внутреннему массиву, хранящему фактические данные. Он сдвинет данные и изменит размер внутреннего массива.
  2. Реализация метода 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). для этого.

10
0

Ответ #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
0

Ответ #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

2
0

Ответ #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).

2
0