c++ - 如何从另一个 View 设置过滤器?

标签 c++ c++20 range-v3

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 循环的情况下做到这一点?

最佳答案

应该是这样的:

  • zip v1v2 ,
  • filter基于.second每个元素具有您喜欢的条件
  • transform只保留.first幸存元素的数量

Here's a working demo :

#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> 的 lambda在其输入 std::pair .

不幸的是std::get<0>不能独立存在,因为它有几个过载(std::pairstd::tuplestd::arraystd::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<>{} 的柯里化(Currying)版本。

    auto constexpr equal_to = curry<2>(std::equal_to<>{});

并想出这个:

    auto result = zip(v1, v2) | filter(compose(equal_to(3), get<1>))
                              | transform(get<0>);

巴里在评论中指出transform(get<0>)实际上是ranges::views::keys ,因此代码可以进一步简化:

    auto result = zip(v1, v2) | filter(compose(equal_to(3), get<1>))
                              | keys;

在另一条评论中指出了一些我从未想过的事情:filter也需要一个投影函数,所以filter(compose(equal_to(3), get<1>))filter(equal_to(3), get<1>) 执行相同的工作:

    auto result = zip(v1, v2) | filter(equal_to(3), get<1>)
                              | keys;

最后,get<1>elements<1> (无论在哪里,我还没有找到它:D),所以我们可以不用 Boost.Hof 的 BOOST_HOF_LIFT宏。

关于c++ - 如何从另一个 View 设置过滤器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71143460/

相关文章:

c++ - 如何在 C++ 中编写正确的哈希表析构函数

c++ - 为什么带有指针子对象的文字类类型的constexpr表达式不能是非类型模板参数

c++ - 为什么 std::ranges::view_interface 使用 CRTP

c++ - 为什么将 `const char[N]` 和 `const char*` 传递给 view::c_str() 会产生不同的二进制文件,而 string_view 会产生相同的二进制文件?

c++ - D3DXVec3Unproject 在 C++ 中不准确

c++ - 无法从 friend 类访问私有(private)和公共(public)成员

c++ - 如何使用 QSettings 在 Qt 应用程序中加载设置

c++ - catch 内的 co_await 不再使用 GCC12 进行编译

c++ - 使用 'overloaded' lambdas 在函数中使用 std::array

c++ - Range-v3 View 组合和 View 计算并行化