0

Is there a standard algorithm in the library that does the job of the following for-loop?

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>


int main( )
{
    const char oldFillCharacter { '-' };
    std::vector<char> vec( 10, oldFillCharacter ); // construct with 10 chars
    // modify some of the elements
    vec[1] = 'e';
    vec[7] = 'x';
    vec[9] = '{';

    const char newFillCharacter { '#' };

    for ( auto& elem : vec ) // change the fill character of the container
    {
        if ( elem == oldFillCharacter )
        {
            elem = newFillCharacter;
        }
    }

    // output to stdout
    std::copy( std::begin( vec ), std::end( vec ),
               std::ostream_iterator<char>( std::cout, " " ) );
    std::cout << '\n';
    /* prints: # e # # # # # x # { */
}

I want to replace the above range-based for-loop with a one-liner if possible. Is there any function that does this? I looked at std::for_each but I guess it's not suitable for such a scenario.

digito_evo
  • 3,216
  • 2
  • 14
  • 42
  • 3
    How about plain [`std::replace`](https://en.cppreference.com/w/cpp/algorithm/replace)? – Some programmer dude Apr 08 '22 at 07:35
  • Tell us what you are trying to do, on a high level. In that code, there are several things going on, and what are we supposed to be pinpointing? – PaulMcKenzie Apr 08 '22 at 07:35
  • So to boil this down, are you simply trying to replace one value with another in a sequence of values? If so, that's what you should state up front -- no need to show code or other things that may confuse what you are actually trying to accomplish. – PaulMcKenzie Apr 08 '22 at 07:40
  • @PaulMcKenzie Yes. Simple as that. I just wanted a one-liner instead of a dummy loop. – digito_evo Apr 08 '22 at 07:42
  • Well, googling "STL algorithm to replace" would have probably gotten you to `std::replace` or `std::replace_if`. Doing a web search for `for` loops wouldn't take you to what you are looking for. – PaulMcKenzie Apr 08 '22 at 07:44
  • @PaulMcKenzie I forgot to Google search. I just kept on searching on cppreference and didn't even search for the word *replace*!! – digito_evo Apr 08 '22 at 07:48

3 Answers3

7

This loop will replace every occurrence of oldFillCharacter with newFillCharacter. If you don't want to do something more fancy std::replace looks good:

std::replace(std::begin(vec), std::end(vec), oldFillCharacter, newFillCharacter);

Or a bit simpler with std::ranges::replace:

std::ranges::replace(vec, oldFillCharacter, newFillCharacter);
Lukas-T
  • 11,133
  • 3
  • 20
  • 30
  • 1
    I was totally unaware of this algorithm. Seems like the most suitable one. Also thanks for suggesting the `ranges` variation! – digito_evo Apr 08 '22 at 07:47
2

You can use std::for_each.

std::for_each(vec.begin(), vec.end(), [](char& elem) { 
    if ( elem == oldFillCharacter ) elem = newFillCharacter;
    });
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
2
std::replace(vec.begin(), vec.end(), '_', '#');
JBahn77
  • 64
  • 3