D.R.
D.R.

Reputation: 21194

Take & remove elements from collection

What's the most performant way to remove n elements from a collection and add those removed n elements to an already existing, different, collection?

Currently I've got this:

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

However, this doesn't look performant at all to me (multiple linear algorithms instead of only one).

A possible solution may of course change the collection implementation - as long as the following requirements are met:

Hint: entries do not necessarily implement Equals() or GetHashCode().

What's the most performant way to reach my goal?


As it has been obviously too hard to understand my performance considerations, here once more my code example:

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 steps in total => I want to reduce it to a single 1000 steps.

Upvotes: 4

Views: 7191

Answers (2)

chrischu
chrischu

Reputation: 3117

With your use case the best data structure seems to be a queue. When using a queue your method can look this this:

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();
}

Upvotes: 2

XSBen
XSBen

Reputation: 31

The previous function only returns half results. You should use:

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();
}

Upvotes: 3

Related Questions