2013-09-03 2 views
2

Какой самый эффективный способ удалить n элементов из коллекции и добавить эти удаленные n элементов в уже существующую, другую, коллекцию?Возьмите и удалите элементы из коллекции

В настоящее время у меня есть это:

var entries = collection.Take(5).ToList(); 
foreach(var entry in entries) 
    collection.Remove(entry); 
otherCollection.AddRange(entries); 

Однако, это не выглядит производительным вообще мне (нескольких линейных алгоритмов вместо одного).

Возможное решение может конечно изменить реализацию коллекции - до тех пор, как следующие требования:

  • otherCollection должен реализовать IEnumerable<T>, в настоящее время типа List<T>
  • collection должен реализовать ICollection<T>, он в настоящее время относится к типу LinkedList<T>

Подсказка: записи необязательно реализуются Equals() или GetHashCode().

Какой самый эффективный способ достичь моей цели?


Как это было, очевидно, слишком трудно понять мои соображения производительности, здесь еще раз мой пример кода:

var entries = collection.Take(1000).ToList(); // 1000 steps 
foreach(var entry in entries) // 1000 * 1 steps (as Remove finds the element always immediately at the beginning) 
    collection.Remove(entry); 
otherCollection.AddRange(entries); // another 1000 steps 

= 3000 шагов в общем => Я хочу, чтобы свести его к одному 1000 шаги.

+3

У вас всегда есть линейный поиск с операцией O (n), нет ничего лучше с коллекцией. –

+0

Я думаю, что коллекция имеет RemoveAll (collection.Take (5)) –

+0

@TimSchmelter: речь идет не о коллекции или нелинейном поиске. Речь идет о том, как избежать * множественных * O (n) операций. Смотрите мой пример кода! –

ответ

2

С вашим вариантом использования лучшая структура данных кажется очередью. При использовании очереди ваш метод может выглядеть так:

public static IEnumerable<T> TakeAndRemove<T>(Queue<T> queue, int count) 
{ 
    count = Math.Min(queue.Count, count); 
    for (int i = 0; i < count; i++) 
     yield return queue.Dequeue(); 
} 
2

Предыдущая функция возвращает только половину результата. Вы должны использовать:

public static IEnumerable<T> TakeAndRemove<T>(Queue<T> queue, int count) 
{ 
    for (int i = 0; i < count && queue.Count > 0; i++) 
     yield return queue.Dequeue(); 
} 
Смежные вопросы