std::find_if 个具有重复数据的自定义对象 std::vector
std::find_if on std::vector of custom objects with duplicate data
考虑以下场景:
typedef struct myStruct
{
int cn;
std::string dn;
} MyStruct;
int main()
{
std::vector<MyStruct> v;
// fill some data
...
...
int c = 1;
std::vector<MyStruct>::iterator it = std::find_if(v.begin(), v.end(),
[c](const MyStruct& m) -> bool { return m.cn == c; });
// use 'it' to do stuff
}
如果v
包含MyStruct
个对象,使得成员变量cn
在多个条目中具有值c (=1)
,如何处理这种情况?作为 std::find_if()
returns 指向范围中第一个元素的迭代器,其余元素呢?
find_if
找到范围内的第一个元素和 return 的迭代器。对于 find all 你可以写循环,每次都会从 it
:
搜索
std::vector<MyStruct>::iterator it = v.begin();
while (it != v.end())
{
it = std::find_if(it, v.end(),
[c](const MyStruct& m) -> bool { return m.cn == c; });
if (it != v.end())
{
// process founded item
++it;
}
}
或者您可以对序列进行排序并使用 equal_range 算法,这将 return std::pair
个迭代器。
对于当前的标准库,您必须使用谓词(如果可以使用 C++11/14 则使用 lambda)在 std::find_if
上编写一个循环,或者使用 std::copy_if
来将每个匹配项复制到新序列。
当 Ranges proposal 可用时(在技术规范和 C++17 中),事情会变得容易得多,例如您将能够编写一个单一的可组合视图和操作链:
#include <range/v3/all.hpp>
#include <iostream>
#include <vector>
using namespace ranges;
int main()
{
auto const is_even = [](auto x) { return x % 2 == 0; };
auto const print = [&](auto x) { std::cout << x << ","; return x; };
std::vector<int> v { 1, 11, 42, 57, 63, 72 };
v | view::filter(is_even) | action::transform(print);
}
Live On Coliru (already works with the range-v3 library).
考虑以下场景:
typedef struct myStruct
{
int cn;
std::string dn;
} MyStruct;
int main()
{
std::vector<MyStruct> v;
// fill some data
...
...
int c = 1;
std::vector<MyStruct>::iterator it = std::find_if(v.begin(), v.end(),
[c](const MyStruct& m) -> bool { return m.cn == c; });
// use 'it' to do stuff
}
如果v
包含MyStruct
个对象,使得成员变量cn
在多个条目中具有值c (=1)
,如何处理这种情况?作为 std::find_if()
returns 指向范围中第一个元素的迭代器,其余元素呢?
find_if
找到范围内的第一个元素和 return 的迭代器。对于 find all 你可以写循环,每次都会从 it
:
std::vector<MyStruct>::iterator it = v.begin();
while (it != v.end())
{
it = std::find_if(it, v.end(),
[c](const MyStruct& m) -> bool { return m.cn == c; });
if (it != v.end())
{
// process founded item
++it;
}
}
或者您可以对序列进行排序并使用 equal_range 算法,这将 return std::pair
个迭代器。
对于当前的标准库,您必须使用谓词(如果可以使用 C++11/14 则使用 lambda)在 std::find_if
上编写一个循环,或者使用 std::copy_if
来将每个匹配项复制到新序列。
当 Ranges proposal 可用时(在技术规范和 C++17 中),事情会变得容易得多,例如您将能够编写一个单一的可组合视图和操作链:
#include <range/v3/all.hpp>
#include <iostream>
#include <vector>
using namespace ranges;
int main()
{
auto const is_even = [](auto x) { return x % 2 == 0; };
auto const print = [&](auto x) { std::cout << x << ","; return x; };
std::vector<int> v { 1, 11, 42, 57, 63, 72 };
v | view::filter(is_even) | action::transform(print);
}
Live On Coliru (already works with the range-v3 library).