转换字符串向量:基于先前的值跳过元素
Transform vector of strings : skip elements based on the previous value
我需要将字符串向量转换为小写,但我需要保留文件名的案例。它们由以前的字符串令牌"文件"或" out"确定。
#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
template <class T>
void print(const T& v) {
std::copy(v.begin(), v.end(),
std::ostream_iterator<typename T::value_type>(std::cout, "n"));
}
std::string lowercase(const std::string& s)
{
std::string result(s);
std::transform(result.begin(), result.end(), result.begin(), ::tolower);
return result;
}
int main() {
std::vector<std::string> tokens {"Col1", "Col2", "File", "FileIn.dat", "Out", "FileOut.dat"};
std::transform(tokens.begin(), tokens.end(), tokens.begin(), lowercase);
// how to replace lowercase() with a lambda that will take the previous
// element into account while converting an element into lowercase
print(tokens);
return 0;
}
在上面的代码中,结果应为
{"col1", "col2", "file", "FileIn.dat", "out", "FileOut.dat"};
在"文件"answers" out"之后保留字符串的情况。
有没有办法使用std::transform
和lambda
函数?
是的。您可以这样使用捕获的lambda:
bool is_filename = false;
std::transform(tokens.begin(), tokens.end(), tokens.begin(),
[&is_filename] (auto &s) {
if (is_filename)
is_filename = false;
else
{
s = lowercase (s);
is_filename = s == "file" || s == "out";
}
return s;
});
输出:
col1
col2
file
FileIn.dat
out
FileOut.dat
实时演示
是。您可以捕获一些状态,并根据所见状态进行设置。但是,您不应该使用std::transform
,因为它不能保证内端遍历。您必须使用std::for_each
。
int main() {
std::vector<std::string> tokens {"Col1", "Col2", "File", "FileIn.dat", "Out", "FileOut.dat"};
bool toggle = true;
auto lowercase = [&toggle](std::string & s)
{
if (toggle)
{
std::transform(s.begin(), s.end(), s.begin(), ::tolower);
}
toggle = (s == "file") || (s == "out");
}
std::for_each(tokens.begin(), tokens.end(), tokens.begin(), lowercase);
print(tokens);
return 0;
}
有没有办法使用std :: transform and lambda函数来执行此操作?
std::transform
不能保证操作员的固定申请。因此,如果我们需要将std::transform
应用于此问题,则最好是二进制操作员的过载:
live demo
std::vector<std::string> tokens {"Col1", "Col2", "File", "FileIn.dat", "Out", "FileOut.dat"};
{
// The first element must not be file name.
tokens[0] = lowercase(tokens[0]);
std::vector<std::string> dummy;
std::transform(
std::next(tokens.begin()), tokens.end(), tokens.begin(),
std::back_inserter(dummy),
[](auto& target, const auto& prev)
{
const auto prevLower = lowercase(prev);
const auto isFileName = (prevLower == "file") || (prevLower == "out");
if(!isFileName){
target = lowercase(target);
}
return "";
});
}
print(tokens);
相关文章:
- 如何在 Arduino 字符串的开头添加元素.类似于 JS unshift();
- C++函数,它将数组、谓词和运算符作为参数,并将运算符应用于满足谓词的数组元素
- 将函数应用于元组中的每个元素,将每个元素强制转换为类型包中的不同类型,然后作为参数包传递
- 如何初始化依赖于先前条目的可变参数模板?
- 将函数应用于特征矩阵中的所有元素,而无需循环
- 检查元素是否存在于二维矢量中
- 就地合并,类似于 std::vector 中的元素
- CUDA C/C 访问先前的数组元素
- 仅当元组中存在该类型时,将功能应用于元组元素
- 复制 std::vector,但将 lambda 应用于每个元素
- 转换字符串向量:基于先前的值跳过元素
- 将二进制操作员应用于数组中的每个元素
- C 如何将函数应用于向量元素
- 为什么 OpenCL 嵌套循环仅适用于某些元素
- 是否可以将std ::函数应用于特征矩阵的每个元素
- 以编程方式推断出枚举的大小,独立于其元素的价值
- 独立于元素内存管理的向量上的函数
- 将相同的功能应用于不同大小的N数组的每个元素
- 将函数应用于数组向量的元素
- 为依赖于先前值的矩阵运行并行代码