0

I have a collection

ObservableCollection<PathInfo> _pathInfos = new ObservableCollection<PathInfo>();

and the corresponding sorted view:

  CollectionView _sortedPathInfos = CollectionViewSource.GetDefaultView(_pathInfos);
  _sortedPathInfos.SortDescriptions.Add(new SortDescription("LastAccess", ListSortDirection.Descending));

Now I want to ensure that not more than _maxItems are in the source collection. The oldest items that exceed the max count shall be removed. To achieve this I have to write quite many lines of code:

private void ensureCount()
{
  var removes = new List<PathInfo>();

  int count = 0;
  foreach (PathInfo info in _sortedPathInfos)
  {
    if (++count > _maxItems)
      removes.Add(info);
  }

  foreach (var remove in removes)
    _pathInfos.Remove(remove);
}

Are there better (shorter) ways to do this?

2 Answers2

0

LINQ can help you.

What about

_sortedPathInfos.View.Skip(_maxItems).ToList().ForEach(x => _pathInfos.Remove(x));

ObservableCollection does not support RemoveRange, and fires "element removed" event each time you remove something from _pathInfos which is pretty inefficient in my opinion, when dealing with large lists.

Why does ObservableCollection not support bulk changes? this thread has few potential fixes, in case you are interested.

Community
  • 1
  • 1
Erti-Chris Eelmaa
  • 25,338
  • 6
  • 61
  • 78
  • Where do you find the `ObservableCollection.Remove` method which can remove an `IEnumerable`? – King King Dec 08 '13 at 10:42
  • That's why I said you might need to add .ToList(). You can always create your own extension method. – Erti-Chris Eelmaa Dec 08 '13 at 10:54
  • The point is there is not such a method `Remove` with such an overload. `Remove` accepts only an instance of type `T`, in this case it's `PathInfo`, not an instance of `List` or `IEnumerable`. You don't even feel that it's wrong? Here is the link to the description for `ObservableCollection.Remove` method from MSDN http://msdn.microsoft.com/en-us/library/ms132413(v=vs.110).aspx – King King Dec 08 '13 at 10:56
  • Ok, I misunderstood. Changed my post. Thanks. – Erti-Chris Eelmaa Dec 08 '13 at 11:08
  • I tried your solution with a dependency to LINQ (using System.Linq;) but I get the error "CS1061" meaning that Skip() is not found as member of ICollectionView and no such extention method exists. – Michael Podlejska Dec 08 '13 at 13:23
  • CollectionView has .View property that exposes sorted IEnumerable. I do believe if you just use _sortedPathInfos.View.Skip(...) then it should be fine. Updated my post with that. – Erti-Chris Eelmaa Dec 08 '13 at 22:32
  • OK, thanks. As I want to **keep** a specific number of items it should be `_sortedPathInfos.View.Take(_maxItems).ToList().ForEach(x => _pathInfos.Remove(x));` then. – Michael Podlejska Dec 10 '13 at 17:54
0

With LINQ you can use "Take" to get the desired amount of elements out of an enumeralbe:

_sortedPathInfos.Take(20);

Have a look at: http://msdn.microsoft.com/en-us/library/bb503062%28v=vs.90%29.aspx

Patric
  • 2,789
  • 9
  • 33
  • 60