はじめに
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; }