Calling a function on every element of a C++ vector

C++FunctionVector

C++ Problem Overview


In C++, is there a way to call a function on each element of a vector, without using a loop running over all vector elements? Something similar to a 'map' in Python.

C++ Solutions


Solution 1 - C++

Yes: std::for_each.

#include <algorithm> //std::for_each

void foo(int a) {
    std::cout << a << "\n";
}

std::vector<int> v;

...

std::for_each(v.begin(), v.end(), &foo);

Solution 2 - C++

You've already gotten several answers mentioning std::for_each.

While these respond to the question you've asked, I'd add that at least in my experience, std::for_each is about the least useful of the standard algorithms.

I use (for one example) std::transform, which is basically a[i] = f(b[i]); or result[i] = f(a[i], b[i]); much more frequently than std::for_each. Many people frequently use std::for_each to print elements of a collection; for that purpose, std::copy with an std::ostream_iterator as the destination works much better.

Solution 3 - C++

On C++ 11: You could use a lambda. For example:

std::vector<int> nums{3, 4, 2, 9, 15, 267};

std::for_each(nums.begin(), nums.end(), [](int &n){ n++; });

ref: http://en.cppreference.com/w/cpp/algorithm/for_each

Solution 4 - C++

If you have C++11, there's an even shorter method: ranged-based for. Its purpose is exactly this.

std::vector<int> v {1,2,3,4,5};

for (int element : v)
    std::cout << element; //prints 12345

You can also apply references and const to it as well, when appropriate, or use auto when the type is long.

std::vector<std::vector<int>> v {{1,2,3},{4,5,6}};

for (const auto &vec : v)
{
    for (int element : vec)
        cout << element;
    
    cout << '\n';
} 

Output:

123
456

Solution 5 - C++

Use for_each:

// for_each example
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

void myfunction (int i) {
  cout << " " << i;
}

struct myclass {
  void operator() (int i) {cout << " " << i;}
} myobject;

int main () {
  vector<int> myvector;
  myvector.push_back(10);
  myvector.push_back(20);
  myvector.push_back(30);

  cout << "myvector contains:";
  for_each (myvector.begin(), myvector.end(), myfunction);

  // or:
  cout << "\nmyvector contains:";
  for_each (myvector.begin(), myvector.end(), myobject);

  cout << endl;

  return 0;
}

Solution 6 - C++

The OP mentions the map function in Python.

This Python function actually applies a function to every element of a list (or iterable) and returns a list (or iterable) that collects all results.

In other words, it does something like this:

def f( x ) : 
   """ a function that computes something with x"""
   # code here 
   return y 

input = [ x1, x2, x3, ... ]
output = map( func, input )  

# output is  now [ f(x1), f(x2), f(x3), ...] 

Hence, the closest C++ standard-library equivalent to Python's map is actually std::transform (from the <algorithm> header).

Example usage is as follows:

#include <vector>
#include <algorithm> 
using namespace std;

double f( int x ) { 
   // a function that computes the square of x divided by 2.0 
   return x * x / 2.0 ;
}

int main( ) {
  vector<int> input{ 1, 5, 10 , 20};
  vector<double> output;
  output.resize( input.size() ); // unfortunately this is necessary

  std::transform( input.begin(), input.end(), output.begin(), f );

  // output now contains  { f(1), f(5), f(10), f(20) }
  //                     = { 0.5, 12.5,  50.0, 200.0 } 
  return 0;
}   

Solution 7 - C++

You can use std::for_each which takes a pair of iterators and a function or functor.

Solution 8 - C++

Thought I would share std::ranges equivalents for for_each and transform, should anyone prefer them:

std::vector<int> v;

std::ranges::for_each(v,[](const auto& n) {});

const auto squared = v | std::views::transform([](const auto& n) { return n*2; });

Running on godbolt: https://godbolt.org/z/zYME6b

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionvikasprajView Question on Stackoverflow
Solution 1 - C++Oliver CharlesworthView Answer on Stackoverflow
Solution 2 - C++Jerry CoffinView Answer on Stackoverflow
Solution 3 - C++Indy9000View Answer on Stackoverflow
Solution 4 - C++chrisView Answer on Stackoverflow
Solution 5 - C++Alexander PoluektovView Answer on Stackoverflow
Solution 6 - C++MateoView Answer on Stackoverflow
Solution 7 - C++juanchopanzaView Answer on Stackoverflow
Solution 8 - C++A.FagrellView Answer on Stackoverflow