【问题标题】:ranges::views::group_by-like function applying predicate to consecutive elements?range::views::group_by-like 函数将谓词应用于连续元素?
【发布时间】:2021-05-04 17:50:17
【问题描述】:

在下面的小示例中,我试图通过连续元素之间的差异为 1 来对元素进行分组。然而,正如输出所示,group_by 的谓词是在当前元素和组的第一个元素之间评估的已处理。

#include <iostream>
#include <range/v3/view/group_by.hpp>

int main() {
    using ranges::views::group_by;
    std::vector<int> v{1,2,3,6,7,8,9,12,14,15};
    for (auto i : v | group_by([](auto x2,auto x1){ return x2 - x1 == 1; })) {
        std::cout << i << '\n';
    }
}

Range-v3 是否提供了一种方法来评估组中连续元素之间的谓词?

我曾经问过the same question for Haskell,结果是namesake function is on Hackage

【问题讨论】:

  • 我推测这不存在。但是 - 你不能自己写吗?此外,当并非所有元素都需要满足相同的标准时,我不会将其称为 group_by 而是其他名称。
  • @einpoklum,我希望现在更清楚了。在我的意图中,每个组中的所有元素都必须是组中的前一个元素 + 1。好吧,整个向量上的第一个元素没有前一个元素......
  • 其实问题已经很清楚了,我只是提个建议。取group_by的源,from here,改Pred结构做你想做的应该不会太难。
  • 这是一种不同的算法,您所描述的算法与通常认为的“分组依据”相反。我在一些函数式编程库中看到它被称为“group with”
  • @AluanHaddad,我猜如果当前的group_by 被称为group_with,那么我描述的不同算法的一个好名字可能是group_by。最后,它们只是“稍微”不同的算法的两个不同名称。至于其他 FP 语言,根据我问题中的链接,Haskell 有Data.List.groupBy(类似于ranges::views::group_by)和Data.List.GroupBy.groupBy

标签: c++ functional-programming grouping range-v3 list-processing


【解决方案1】:

这是我尝试组合 Range-v3 中已有的内容以获得我想要的东西的丑陋结果。

#include <iostream>
#include <range/v3/view/group_by.hpp>
#include <range/v3/view/transform.hpp>
#include <range/v3/view/iota.hpp>
#include <range/v3/view/concat.hpp>
#include <range/v3/view/zip_with.hpp>

constexpr auto elem_and_distance_from_previous
    = [](int x, int y){ return std::make_pair(x,x - y); };
constexpr auto second_is_1 = [](auto,auto x){ return x.second == 1; };
constexpr auto get_first = [](auto x){ return x.first; };

using namespace ranges::views;
int main() {
    std::vector<int> v{1,2,3,6,7,8,9,12,14,15};
    auto w = zip_with(elem_and_distance_from_previous,v,concat(iota(0,1),v))
           | group_by(second_is_1)
           | transform([](auto x){ return x | transform(get_first); });
    std::cout << w << '\n';
}
// outputs [[1,2,3],[6,7,8,9],[12],[14,15]]

可能正如@einpoklum 在评论中所建议的那样,对原始group_by 进行复制粘贴编辑会好得多。但是我问了这个问题,因为我想知道 Range-v3 中是否已经有一种方法可以实现我的意思。

【讨论】:

    猜你喜欢
    • 2016-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多