En C++, existe-t-il un moyen d'appeler une fonction sur chaque élément d'un vecteur, sans utiliser de boucle qui passe sur tous les éléments vectoriels? Quelque chose de similaire à une "carte" en Python.
Oui: std::for_each
.
void foo(int a) {
std::cout << a << "\n";
}
std::vector<int> v;
...
std::for_each(v.begin(), v.end(), &foo);
Vous avez déjà obtenu plusieurs réponses mentionnant std::for_each
.
Bien que ceux-ci répondent à la question que vous avez posée, j'ajouterais qu'au moins d'après mon expérience, std::for_each
Concerne les les moins utiles des algorithmes standard.
J'utilise (pour un exemple) std::transform
, Qui est essentiellement a[i] = f(b[i]);
ou result[i] = f(a[i], b[i]);
beaucoup plus fréquemment que std::for_each
. De nombreuses personnes utilisent fréquemment std::for_each
Pour imprimer des éléments d'une collection; à cet effet, std::copy
avec un std::ostream_iterator
comme destination fonctionne beaucoup mieux.
Sur C++ 11: vous pouvez utiliser un lambda. Par exemple:
std::vector<int> nums{3, 4, 2, 9, 15, 267};
std::for_each(nums.begin(), nums.end(), [](int &n){ n++; });
Utilisation 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;
}
Si vous avez C++ 11, il existe une méthode encore plus courte: à distance pour . Son but est exactement cela.
std::vector<int> v {1,2,3,4,5};
for (int element : v)
std::cout << element; //prints 12345
Vous pouvez également lui appliquer des références et const, le cas échéant, ou utiliser auto lorsque le type est 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';
}
Production:
123
456
Vous pouvez utiliser std :: for_each qui prend une paire d'itérateurs et une fonction ou un foncteur.
L'OP mentionne la fonction map
en Python. Cette fonction applique en fait une fonction à chaque élément d'une liste (ou itérable) et renvoie une liste (ou itérable) qui recueille tous les résultats. En d'autres termes, il fait quelque chose comme ceci:
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), ...]
Par conséquent, l'équivalent de la bibliothèque standard C++ la plus proche de la carte de Python est en fait std::transform
(à partir de l'en-tête).
Voici un exemple d'utilisation:
#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;
}