简体   繁体   中英

remove element by position in a vector<string> in c++

I have been trying to remove the value False and 0;0 from a vector<string> plan; containing the following

1003;2021-03-09;False;0;0;1678721F
1005;2021-03-05;False;0;0;1592221D
1005;2021-03-06;False;0;0;1592221D
1003;2021-03-07;False;0;0;1592221D
1003;2021-03-08;False;0;0;1592221D
1004;2021-03-09;False;0;0;1592221D
1004;2021-03-10;False;0;0;1592221D
1001;2021-03-11;False;0;0;1592221D

but the solutions I have found only work with int, and I tried the following

remove(plan.begin(), plan.end(), "False");

also with erase , but it didn't work

what is the mistake that I am making, or how should I do to eliminate the values that I want, which are in the position [2] [3] and [4] , thanks for any help.

[Note: This answer assumes that each line corresponds to an element in the vector]

With the statement

remove(plan.begin(), plan.end(), "False");

you try to remove all elements from the vector that are equal to "False" .

You need to iterate over the vector and erase the sub-string from each and every string in the vector.

For example you can use a range for loop to iterate over all the strings (or rather references to them), and then use the std::string functions find to find the sub-strings you want to remove and replace to replace the sub-strings with empty strings (ie nothing).

[ Note : With the assumption 1003;2021-03-09;False;0;0;1678721F corresponding to a row inside std::vector<string> ]


std::remove : Removes from the vector either a single element (position) or a range of elements ([first, last)).

In case std::vector<string> plan contains value False then it is removed.

  std::vector < std::string > plan =
  {
     "1003","2021-03-09","False","0;0","1678721F"
      
  };
  
  std::remove(plan.begin(),plan.end(),"False");

In your case you need to remove given sub-string from each row of the plan . You need to iterate through all the rows to remove given value using std::string::erase .

  std::vector < std::string > plan =
  {
     "1003;2021-03-09;False;0;0;1678721F",
      "1005;2021-03-05;False;0;0;1592221D",
      "1005;2021-03-06;False;0;0;1592221D",
      "1003;2021-03-07;False;0;0;1592221D",
      "1003;2021-03-08;False;0;0;1592221D",
      "1004;2021-03-09;False;0;0;1592221D",
      "1004;2021-03-10;False;0;0;1592221D",
      "1001;2021-03-11;False;0;0;1592221D"};

    for (auto & e:plan)
    {
      //As position of False;0;0; is at a fixed index, i.e: from index:16, 10 characters are removed
      e.erase (16, 10);
    }

To generalize, You can make use of std::String::find to find a sub-string and erase it.

void removeSubstrs(string& s, string p) { 
  string::size_type n = p.length();
  for (string::size_type i = s.find(p);
      i != string::npos;
      i = s.find(p))
      s.erase(i, n);
}

int
main ()
{

  std::vector < std::string > plan =
  {
     "1003;2021-03-09;False;0;0;1678721F",
      "1005;2021-03-05;False;0;0;1592221D",
      "1005;2021-03-06;False;0;0;1592221D",
      "1003;2021-03-07;False;0;0;1592221D",
      "1003;2021-03-08;False;0;0;1592221D",
      "1004;2021-03-09;False;0;0;1592221D",
      "1004;2021-03-10;False;0;0;1592221D",
      "1001;2021-03-11;False;0;0;1592221D"};

    for (auto & e:plan)
    {
      removeSubstrs (e, ";False;0;0");
    }
    
    for (auto e:plan)
        std::cout << e << std::endl;


  return 0;
}

If you are sure that there is only one occurrence of "First" and "0;0" in your vector, you can use something like this:

std::string EraseFirstSubString(
   const std::string & main_str,
   const std::string & sub_str)
{
   std::string new_main_str = main_str;
   size_t pos = new_main_str.find(sub_str);
   if (pos != std::string::npos)
   {
      new_main_str.erase(pos, sub_str.length());
   }
   return new_main_str;
}

int main()
{
   std::vector<std::string> plan = {
      "1003;2021-03-09;False;0;0;1678721F",
      "1005;2021-03-05;False;0;0;1592221D",
      "1005;2021-03-06;False;0;0;1592221D",
      "1003;2021-03-07;False;0;0;1592221D",
      "1003;2021-03-08;False;0;0;1592221D",
      "1004;2021-03-09;False;0;0;1592221D",
      "1004;2021-03-10;False;0;0;1592221D",
      "1001;2021-03-11;False;0;0;1592221D" 
   };

   for (std::string & str : plan)
   {
      str = EraseFirstSubString(str, "False");
      str = EraseFirstSubString(str, "0;0");
   }
};

But, if you think that you may have many occurrences of those sub-strings, you should improve a little bit your sub-string removing mechanism like this:

std::string EaraseSubStrings(
   const std::string & main_str, 
   const std::string & sub_str)
{
   std::string new_main_str = main_str;
   size_t pos = new_main_str.find(sub_str);

   while (pos != std::string::npos)
   {
      new_main_str.erase(pos, sub_str.length());
      pos = new_main_str.find(sub_str);
   }
   return new_main_str;
}

If you already have a vector of individual std::string objects, you can easily use the operations that the strings library offers.

#include <algorithm>
#include <vector>
#include <string>

// before C++20 change constexpr to inline
constexpr void change(std::vector<std::string>& sv, std::string const& rem) {
  for_each(beign(sv),end(sv), [&rem](std::string& s) {
    s.erase(std::min(s.size(),s.find(rem)), rem.size());
  });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM