Home > Software engineering >  How to remove an item from a list of tuples in c ?
How to remove an item from a list of tuples in c ?

Time:07-26

I'm iterating over my list of tuples : list<tuple<int,int>> edges, and want to remove some elements in it. This is necessary for me to reduce the total overhead as I am working with huge data.

std::list<tuple<int, int>>::iterator it;
for (it = edges.begin(); it != edges.end();   it)
{
  if (get<0>(*it) == 0 || get<1>(*it) == 0){
      edges.remove(*it);
  }

}

As I know, remove(element) works, but here edges.remove(*it) does not. How can I do this correctly?

CodePudding user response:

You can use erase() to specify an element to remove by an iterator.

It returns an iterator for the next element, so don't forget to catch that.

std::list<tuple<int, int>>::iterator it;
for (it = edges.begin(); it != edges.end(); ) // don't increment it here
{
  if (get<0>(*it) == 0 || get<1>(*it) == 0){
      it = edges.erase(it);
  } else {
        it;
  }
}

CodePudding user response:

In C 20, you can simply use a specialization of std::erase_if for std::list to do this.

#include <list>
#include <tuple>

int main() {
  std::list<std::tuple<int, int>> l;
  std::erase_if(l, [](const auto& elem) {
    auto& [first, second] = elem;
    return first == 0 || second == 0; });
}

Demo

However, since std::list itself has a remove_if member function, it is more appropriate to use it directly, since it applies to any C standard.

CodePudding user response:

In my opionion remove_if which is a dedicated and optimized function for a std::list should be used. This will avoid unnecessary indirections.

Please read here about it.

The result will be an efficient one liner.

Please see one of many potential solutions:

#include <iostream>
#include <list>
#include <tuple>

using MyTuple = std::tuple<int,int>;
using MyList = std::list<MyTuple>;

int main() {
    // Define some demo data
    MyList myList{{0,1},{2,3},{4,5},{6,0},{7,8},{9,10},{0,0}};
    
    
    // Predicate function. Define whatever you want
    auto unwanted = [](const MyTuple& t) {return std::get<0>(t)==0 or std::get<1>(t)==0;};
    
    // Remove all unwanted stuff
    myList.remove_if(unwanted);
    
    // Some debug output
    for (const auto&[l,r] : myList) 
        std::cout << l << ' ' << r << '\n';
}
  • Related