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