snippetcsharpMajor
Sort ObservableCollection after added new item
Viewed 0 times
afteritemnewaddedsortobservablecollection
Problem
For a WPF application, I have to sort the items in
In order to keep the observable functionality for binding element, the
Any improvement about this?
ObservableCollection after Added new item. public void UpdateSource(ObservableCollection source, SomeType newItem)
{
source.Add(newItem);
SortSource(source, newItem);
}
private void SortSource(ObservableCollection source, SomeType item)
{
var oldIndex = source.IndexOf(item);
var list = source.OrderBy(_=>_.SomeProperty).ToList();
var newIndex = list.IndexOf(item);
source.Move(oldIndex, newIndex);
}In order to keep the observable functionality for binding element, the
ObservableCollection reference cannot be changed, so I used an assistance list to help me sort the souce.Any improvement about this?
Solution
Your code unnecessarily sorts the whole collection on each insert (which is likely going to be O(n log n)). It also produces two events for each insert (one for
What I would do:
A simple implementation for that could look like this:
This could be made faster by using binary search to find the index. Though the total complexity is still going to be O(n), even with binary search, because
This means that using binary search would help the most if you're often inserting items at or near the end of the collection.
Other notes about your code:
I don't think
Add and one for Move), which also isn't necessary.What I would do:
- Find the index where the inserted item belongs.
- Insert the item at that index.
A simple implementation for that could look like this:
public static void AddSorted(this IList list, T item, IComparer comparer = null)
{
if (comparer == null)
comparer = Comparer.Default;
int i = 0;
while (i < list.Count && comparer.Compare(list[i], item) < 0)
i++;
list.Insert(i, item);
}This could be made faster by using binary search to find the index. Though the total complexity is still going to be O(n), even with binary search, because
Insert is O(n) (it has to move all items after the inserted item).This means that using binary search would help the most if you're often inserting items at or near the end of the collection.
Other notes about your code:
public void UpdateSource(ObservableCollection source, SomeType newItem)I don't think
Update is the right name here, this is not a general update, something like AddToSource would be better.source.OrderBy(_=>_.SomeProperty)_ as a parameter name of a lambda is commonly used when you don't care about the value of that parameter. If you do care about it (like here), use something like x, or, even better, a meaningful name.Code Snippets
public static void AddSorted<T>(this IList<T> list, T item, IComparer<T> comparer = null)
{
if (comparer == null)
comparer = Comparer<T>.Default;
int i = 0;
while (i < list.Count && comparer.Compare(list[i], item) < 0)
i++;
list.Insert(i, item);
}public void UpdateSource(ObservableCollection<SomeType> source, SomeType newItem)source.OrderBy(_=>_.SomeProperty)Context
StackExchange Code Review Q#37208, answer score: 31
Revisions (0)
No revisions yet.