'Sort elements alphabetically but keep one always at the beginning
I have elements of the following type stored in a collection.
class Element
{
public:
bool IsDefault { false };
std::wstring Name { };
Element() = default;
Element(const bool isDefault, std::wstring name) : IsDefault { isDefault }, Name { std::move(name) }
{}
bool operator==(const Element& other) const noexcept = default;
};
Note there can only be one element with IsDefault == true. What I want to achieve is sort the collection alphabetically (case-insensitive), but put the one element with IsDefault == true always at the beginning, regardless of its name.
My current code works, but I am looking for a way that is more efficient (as it is now, finding the one element with IsDefault == true takes O(N) and then sorting the collection takes O(N log N) afterwards) ore more idiomatic / requires less code. What can I do to improve it? Is there a way to achieve my goal with a single call to std::ranges::sort or some other function?
I can make use of C++20 features if required.
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector elements { Element(false, L"World"), Element(true, L"Foo"), Element(false, L"Zoo"), Element(false, L"Bar") };
// Find the default element and remove it from the vector.
Element defaultElement;
for (const auto& e : elements)
{
if (e.IsDefault)
{
defaultElement = e;
std::erase(elements, e);
break;
}
}
// Sort the remaining elements alphabetically
std::ranges::sort(elements, [](const Element& a, const Element& b) noexcept
{
const auto& first { a.Name };
const auto& second { b.Name };
return ::_wcsnicmp(first.c_str(), second.c_str(), std::min(first.size(), second.size())) < 0;
});
// Insert the default element at index 0
elements.insert(std::begin(elements), defaultElement);
_ASSERT(elements.at(0).Name == L"Foo");
_ASSERT(elements.at(1).Name == L"Bar");
_ASSERT(elements.at(2).Name == L"World");
_ASSERT(elements.at(3).Name == L"Zoo");
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
