nprogram’s blog

気ままに、プログラミングのトピックについて書いていきます

C++で抽出・変換・集計処理を行う

はじめに

JavaやC#の関数型プログラミングをC++で行ってみました。

数列から、奇数を抽出して、その結果に対して2倍し、統計します。

コード

#include <iostream>
#include <functional>
#include <algorithm>
#include <vector>
#include <numeric>
using namespace std;

void print_num(int num){
    std::cout<< num << std::endl;
}

int filter_map_fold(const std::vector<int>& nums)
{
    std::vector<int> odds;
    
    // filter(抽出)(奇数を抽出)
    std::copy_if(nums.begin(), nums.end(), std::back_inserter(odds), [](int num){ return num % 2;});
    
    // 表示内容を確認
    std::for_each(odds.begin(), odds.end(), print_num);
    
    // Map(変換)(2倍する)
    std::vector<int> doubles;
    std::transform(odds.begin(), odds.end(), std::back_inserter(doubles), [](int num){ return num * 2; } );
    
    // 表示内容を確認
    std::for_each(doubles.begin(), doubles.end(), print_num);
    
    // fold(集計)(統計する)
    int result = std::accumulate(doubles.begin(), doubles.end(), 0, [](int acc, int n) { return acc + n;});
    
    return result;
}

int main(void){
    std::vector<int> nums = {1,2,3,4,5,6,7,8,9,10};
    
    int result = filter_map_fold(nums);
    
    std::cout << "result : " << result << std::endl;
}

Linq for C++

拡張ライブラリであるLinq for C++を使用して、上記のコードを書き直してみます。 コード行数も抑えながらシンプルに記載することができました。

LINQ for C++ (cpplinq) is an extensible C++11 library of higher-order functions for range manipulation. cpplinq draws inspiration from LINQ for C#.

https://archive.codeplex.com/?p=cpplinq

#include <iostream>
#include <vector>
#include "cpplinq.hpp"

void print_num(int num){
    std::cout<< num << std::endl;
}

int filter_map_fold(const std::vector<int>& nums)
{
    return cpplinq::from(nums)
        >> cpplinq::where([](int n) { return (n % 2) != 0; })
        >> cpplinq::select([](int n) { return n * 2; })
        >> cpplinq::aggregate(0, [](int result, int n) { return result + n; });
}

int main(void){
    std::vector<int> nums = {1,2,3,4,5,6,7,8,9,10};
    
    int result = filter_map_fold(nums);
    
    std::cout << "result : " << result << std::endl;
}

参考資料

クロージャデザインパターン