在 C++ 中,是否有一种方法可以在不使用循环遍历整个向量的情况下对向量的每个元素调用一个函数?类似于 Python 中的“map”。
已经有几个回答提到了 std::for_each
。
虽然这些回答回应了你提出的问题,但我想补充一下,至少在我的经验中,std::for_each
是标准算法中最不实用的算法之一。
我更频繁地使用(举一个例子)std::transform
,它基本上是 a[i] = f(b[i]);
或 result[i] = f(a[i], b[i]);
,而不是 std::for_each
。许多人经常使用 std::for_each
打印集合的元素;为此,std::copy
与 std::ostream_iterator
作为目标的结合效果更好。
可以使用: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);
for_each()
的实现很可能只是一个循环,而且由于它使用了模板,所以不应该有任何区别。然而,随着C++17的推出,他们可能会引入并行处理,这对你来说完全透明,而且很可能会更快。 - Alexis WilkeC++ 11中,您可以使用Lambda表达式。例如:
std::vector<int> nums{3, 4, 2, 9, 15, 267};
std::for_each(nums.begin(), nums.end(), [](int &n){ n++; });
for(int& n: nums) n++;
。更少的代码 - 更容易理解。 - KulaGGinOP提到了Python中的map
函数。
实际上,这个Python函数将一个函数应用于列表(或可迭代对象)的每个元素,并返回一个收集所有结果的列表(或可迭代对象)。
换句话说,它做的事情类似于这样:
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), ...]
std::transform
(来自<algorithm>
头文件)。#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;
}
如果你使用的是C++11,有一个更简短的方法:基于范围的for循环。它的目的正是这个。
std::vector<int> v {1,2,3,4,5};
for (int element : v)
std::cout << element; //prints 12345
当适用时,您也可以对它应用引用和const,或者在类型很长时使用auto。
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';
}
输出:
123
456
operator<<(std::cout, element)
。我发帖的主要目的是让原帖作者(以及任何未来的访问者)了解这种语法。不想循环的原因并没有说明,可能只是不想把它全部输入。for_each
中也有循环。第二个示例只是一个示例。它表明您可以随意选择使用其中的任何一个,这使人们可以自由地更改它。另外,谁说你需要修改元素才能在其上调用函数呢? - chrisfor_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;
}
我想分享一下,如果有人喜欢的话,可以使用std::ranges
中的等效函数来替代for_each
和transform
:
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; });
在godbolt上运行:https://godbolt.org/z/zYME6b
std::transform
不保证按顺序应用...要按顺序将函数应用于序列或应用修改序列元素的函数,请使用std::for_each
。 - starriet