Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing an element from a nested list within an object using range-based loops

Tags:

c++

I'm using C++20.

I have an object MyObject that contains a variable std::set<std::set<int>> nestedSet. I need to iterate through nestedSet and remove from the second-level sets an element that matches a search criteria. So far, I've tried the implementations:

void MyObject::removeFromNestedSet(int criteria) {
    for(auto s : nestedSet){
        std::erase_if(s, [&criteria](int i){return i == criteria;});
    }
}

and

void MyObject::removeFromNestedSet(int criteria) {
    for(auto s : nestedSet){
        auto it = s.find(criteria);
        if(it != s.end()){
            s.erase(it, s.end());
        }
    }
}

Viewing the code progression with a debugger, I can see that within the frame of the removeFromNestedSet function, the element in the set matching the criteria IS removed. However, this removal is not reflected when observing the this->nestedSet object.

I haven't worked with C++ in a few years, but I suspect this is an issue with needing the range-based loop to point to the actual nested sets within nestedSet rather than a copy of the nested set?

like image 739
Colin Avatar asked Jan 27 '26 04:01

Colin


1 Answers

You are having difficulty because a std::set's elements are always const.

This is because a std::set's elements are always ordered by their values. Changing a value could violate the order.

You must remove each element from your outer std::set before you can modify it.

void MyObject::removeFromNestedSet(int criteria) {
    std::set<std::set<int>> newNestedSet;

    while ( ! nestedSet.empty() ) {
       // Remove an inner set, so it can be modified
       auto setNode = nestedSet.extract( nestedSet.begin() );

       // Modify the set
       std::erase_if(setNode.value(), [&](int i){return i == criteria;});

       // Place the result in a new set
       newNestedSet.insert(std::move(setNode));
    }

    nestedSet = std::move(newNestedSet);
}

This solution doesn't make any copies of your data and preserves the integrity of any pointers or references to your stored ints.

Note that your sets may be in a different order after your modification.

like image 195
Drew Dormann Avatar answered Jan 28 '26 18:01

Drew Dormann