std::vector v1 {4,2,7,6,4,1};
std::vector v2 {3,0,0,0,0,3};
我想在條件 v2=3 的情況下獲取 v1 中的值
我想要的結果 [4,1]
我嘗試使用過濾器,但它似乎只適用于指定的值。
auto rng = v1 | ranges::views::filter([](int x){return ...;});
如何在不使用 for 回圈的情況下做到這一點?
uj5u.com熱心網友回復:
應該是這樣的:
zipv1和v2,filter基于.second具有您喜歡的條件的每個元素的transform只保留.first幸存的元素
這是一個作業演示:
#include <iostream>
#include <range/v3/view/filter.hpp>
#include <range/v3/view/transform.hpp>
#include <range/v3/view/zip.hpp>
using namespace ranges::views;
int main() {
std::vector v1 {4,2,7,6,4,1};
std::vector v2 {3,0,0,0,0,3};
auto result = zip(v1, v2) | filter([](auto pair){ return pair.second == 3; })
| transform([](auto pair){ return pair.first; });
std::cout << result << std::endl; // prints [4,1]
}
一些改進
請注意,這[](auto pair){ return pair.first; }只是一個std::get<0>在其 input上運行的 lambda std::pair。
不幸的是std::get<0>,它不能獨立存在,因為它有幾個多載(for std::pair, std::tuple, std::array, std::variant)。
簡化代碼的一種方法是
#include <boost/hof/lift.hpp>
然后定義
template<std::size_t N>
auto constexpr get = BOOST_HOF_LIFT(std::get<N>);
這樣您就可以get<0>輕松地四處走動。
鑒于此,在 和 的幫助下boost::hana::compose,boost::hana::curry可以撰寫一個咖喱版本std::equal_to<>{}
auto constexpr equal_to = curry<2>(std::equal_to<>{});
并想出這個:
auto result = zip(v1, v2) | filter(compose(equal_to(3), get<1>))
| transform(get<0>);
Barry 在評論中指出transform(get<0>)實際上是ranges::views::keys,因此代碼可以進一步簡化:
auto result = zip(v1, v2) | filter(compose(equal_to(3), get<1>))
| keys;
In another comment was pointed out something that I never think about: filter takes a projection function too, so filter(compose(equal_to(3), get<1>)) does the same job as filter(equal_to(3), get<1>):
auto result = zip(v1, v2) | filter(equal_to(3), get<1>)
| keys;
And finally, get<1> is elements<1> (wherever that is, I haven't found it yet :D), so we can do without Boost.Hof's BOOST_HOF_LIFT macro.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/425699.html
