【问题标题】:Algorithm name?: Concatenate the ranges returned by a function applied to each element of a range算法名称?:连接由应用于范围的每个元素的函数返回的范围
【发布时间】:2021-07-26 08:19:12
【问题描述】:

也许我错过了什么。 <algorithm> 中有这样的功能吗?如果不是,你会怎么称呼它?这似乎是一种特殊的变换归约风格,它非常具体,需要一个名字:

template <typename Iter, typename OutIter, typename Fn>
void transformed_concatenated(Iter beg, Iter end, OutIter out, Fn f) {
    for (; beg != end; ++beg) {
        for (auto& x : f(*beg)) {
            *out++ = std::move(x);
        }
    }
    return out;
}

也就是说,如果我这样做了

const std::vector<int> input { 0, 1, 2, 3 };
const auto f = [](int n) { return std::vector<int>(n, n * 2 + 1); };
std::vector<int> result;
transformed_concatenated(input.begin(), input.end(), std::back_inserter(result), f);

我会得到3, 5, 5, 7, 7, 7

std::transform_reduce 可以做类似的事情,但我觉得它失去了一些东西。

【问题讨论】:

  • 您能否添加一个关于代码应该做什么的文字描述(除了代码)?我不喜欢依靠对某人代码的解释来确定他们的意图。
  • 这有时被称为flatMap
  • 除了文字说明之外,为函数添加输入和所需输出的示例也很有帮助。

标签: c++ algorithm stl stl-algorithm


【解决方案1】:

使用 C++20 中引入的范围和视图,您可以编写:

std::ranges::copy(input 
                  | std::views::transform(f) 
                  | std::views::join, 
                  std::back_inserter(result));

这是demo


请注意,您的函数f 不正确。应该是

const auto f = [](int n) { return std::vector<int>(n, n); };
                                               // ^____^

获得所需的输出1 2 2 3 3 3。如果你使用大括号来构造向量,你会得到一个包含 2 个元素的向量,两个元素的值都是n,输出将是1 1 2 2 3 3

【讨论】:

  • 不错!考虑到这一点,我想transform_join 将是我老式非范围版本的好名字。
  • @Ben 是的,这对函数来说是个好名字。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多