简体   繁体   中英

Removing all empty elements in a vector from end

Given a std::vector of strings, what is the best way of removing all elements starting from the end that are empty (equal to empty string or whitespace). The removal of elements should stop when a non-empty element is found.

My current method, (work in progress) is something like:

while (Vec.size() > 0 && (Vec.back().size() == 0 || is_whitespace(Vec.back()))
{
    Vec.pop_back();
}

where is_whitespace returns a bool stating if a string is whitespace or not

I suspect that my method will resize the vector at each iteration and that is suboptimal. Maybe with some algorithm it is possible to do in one step.

Input: { "A", "B", " ", "D", "E", " ", "", " " }

Desired Output: { "A", "B", " ", "D", "E" }

As I did not find a good dupe on first glance, here is a simple solution:

// Helper function to see if string is all whitespace
// Can also be implemented as free-function for readablity and
// reusability of course
auto stringIsWhitespace = [](const auto &str)
{
    return std::all_of(
        begin(str), end(str), [](unsigned char c) { return std::isspace(c); });
};

// Find first non-whitespace string from the back
auto it = std::find_if_not(rbegin(Vec), rend(Vec), stringIsWhitespace);
// Erase from there to the end
Vec.erase(it.base(), end(Vec));

Note the unsigned in the lambda due to this gotcha .

Live example thanks to @Killzone Kid .

Here's a better way:

for (auto it = Vec.rbegin(); it != Vec.rend() && is_whitespace(*it); )
{
    it = Vec.erase(it);
}

It will start from the end and stop once non-whitespace has been encountered or the beginning of the vector is reached, whichever comes first. Note that I don't increment the iterator in the for loop.

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