C++/WinRT : Sorting a IObservableVector<T>

Viewed 343

Is there a way I can directly sort a winrt::Windows::Foundation::Collections::IObservableVector<T> without creating a new vector nor converting it to a std::vector<T>?

IObservableVector<int> numbers{ single_threaded_observable_vector<int>() };
numbers.Append(5);
numbers.Append(1);
numbers.Append(3);

std::sort(numbers.begin(), numbers.end());

The std::sort seems not to work on C++/WinRT collections, at least for me.

My further goal is to display sorted and filtered collection of complex objects in a GridView.

If direct sorting is not possible, what's the most efficient way of turning IObservableVector<T> into a std::vector<T>? Vice versa is quite straightforward single_threaded_observable_vector<T>(std::move(vec)).

Edit:

According to Raymond Chen's blog it's possible to copy a IVector<T> into a std::vector<T> with use of IVector<T>.GetMany(UInt32, T[]).

std::vector<int> vec(numbers.Size());
numbers.GetMany(0, vec);

However, I'm still unsure about the performance of copying large collections in a production app. Hope there's a better approach.

1 Answers

Exactly, std::sort only works on iterable collection. But you can implement a sort function on IVector using its method GetAt, SetAt.

But copy it to std::vector is a simpler workaround. Don't worry the copy cost. Sorting a vector needs O(n lg n) times swapping, which is several times slower than O(n) copying. The extra cost can be ignored.

When the size of single data object is huge but the length of vector is not, you can indeed solve this problem indirectly: Initiate an array id : id[i] = i, and sort it by comparing vector[id[i]] and vector[id[j]] (at least IVector supports random access), then you've already got "the sorted vector". That's because id[i] is the index of i-th element. You can access the new sorted vector through vector[id[...]].

Related