『Programming Elixir』より "Think Different(ly)" - Qiitaを読み、Elixir
という言語に関心がわいてきた。
これは Ruby の Enumerable#map のような機能です。 コレクションの各要素に関数を適用し、 その結果を集めた新しいコレクションを返します。
Elixir : Erlang VM 上で動作する Ruby 風味の関数型言語 | プログラマーズ雑記帳
Enum.map([1,2,3], fn(x) -> x * 2 end) #=> [2,4,6]
Enumモジュールにmap関数があるとな?ふむふむ。
最終的にこんなかんじで呼び出せる
std::vector<int> src; // [10, 20, 30]
std::vector<int> changed = Enum::map<int>( src, [](int& x){ return x*=2; });
changed; // [20, 40, 60]
実装してみた(テストつき)
- VisualStudio 2012 使用
#include "stdafx.h"
#include "CppUnitTest.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
#include <vector>
#include <algorithm>
#include <functional>
class Enum
{
public:
template<class T, class Clojure>
static std::vector<T> map(const std::vector<T>& src, Clojure op)
{
std::vector<T> dest = src;
std::transform( std::begin(dest), std::end(dest), std::begin(dest), op );
return dest;
}
};
namespace UnitTest_Elixir_Enum
{
TEST_CLASS(UnitTest_Elixir_Enum)
{
public:
TEST_METHOD(test_int_map)
{
std::vector<int> src = [](){
std::vector<int> s;
s.push_back(10);
s.push_back(20);
s.push_back(30);
return (s);
}();
std::vector<int> changed = Enum::map<int>( src, [](int& x){ return x*=2; });
Assert::AreEqual( 20, changed.at(0));
}
TEST_METHOD(test_string_map)
{
std::vector<std::string> src = [](){
std::vector<std::string> s;
s.push_back("ruby");
s.push_back("elixir");
s.push_back("c++");
return (s);
}();
std::vector<std::string> changed = Enum::map<std::string>( src, [](std::string& x){ x.insert(0, "hello, "); return x; });
Assert::AreEqual( std::string("hello, ruby"), changed.at(0));
}
};
}
たのしいですね!