RKum
RKum

Reputation: 831

Finding element in QList

Suppose I have a struct SignalError which has an element "errName" and many other elements:

typedef struct SignalError
{
    QString errName;
    .....
};

I create QList of this struct:

QList<SignalError> signalErrList;

I will append the struct element to the QList using append call.

SignalError sgErr1 = {"Error_1"};

signalerrList.append(sgErr1);

Before appending the element to the list I want to check if there is any element with the same name "errName" already existing in the QList or not. If it is then I will not add the element to the list. How do I do this?

Also, should I create a list of objects like:

QList<SignalError> signalErrList;

or create list of pointer to the object:

QList<SignalError*> signalErrList;

Upvotes: 1

Views: 2438

Answers (1)

Ben
Ben

Reputation: 9733

You should use QList<SignalError> signalErrList; not a QList of pointers.

If you don’t care about order, you should use a std::set<SignalError> which will give you deduplication automatically.

If you care about order and the O(N) search isn’t a problem, then use QList or std::vector and do

if (auto it = std::find(signalErrList.begin(), signalErrList.end(), sgErr1;
    it == signalErrList.end()) {
    signalErrList.push_back(std::move(sgErr1));
}

which you could (and should) name as a function:

//! A linear-time (O(n)) search followed by push-back if not found
//! API modeled on https://en.cppreference.com/w/cpp/container/set/emplace
template <typename Container, typename Value>
std::pair<typename Container::iterator, bool>
emplaceBackLinearUnique(Container& c, Value&& v) {
    if (auto it = std::find(c.begin(), c.end(), v); it != c.end()) {
        // Return iterator to the found one and say that it wasn't emplaced.
        return { it, false }; 
    }
    // Not found:
    c.emplace_back(std::forward<Value>(v));
    // Return iterator to the new last element and report that it was emplaced:
    return { c.begin() + c.size() - 1, true };
}

which lets you replace. your use case with this.:

emplaceBackLinearUnique(signalErrList, sgErr1);

Upvotes: 2

Related Questions