-
Notifications
You must be signed in to change notification settings - Fork 33
/
Copy pathcpp11_21_for_cppFunctionProm.cpp
125 lines (107 loc) · 4 KB
/
cpp11_21_for_cppFunctionProm.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/************************************************************************
* 代码标签 : algorigthm 中的for_each map reduce 等的实现 进行函数式编程;
* 功能描述 :
* 类 名 称 :
* 版 本 号 : v1.0
* 说 明 :
* 作 者 : dragonfive
* 创建时间 :
* 更新时间 :
************************************************************************
* Copyright @dragonfive 2016 . All rights reserved.
************************************************************************/
#include <iostream>
#include <algorithm>
#include <set>
using namespace std;
//下面是函数式编程里面的for_each
template<typename Collection,typename Func>
void for_each(Collection const &collection,Func func)
{
std::for_each(collection.begin(),collection.end(),func);
}
//下面是函数式编程里面的map,因为c++的for_each不允许对象被修改,所以这里使用transform
//map操作表示对容器中每个元素都执行相同的操作
template <typename Collection,typename unop>
Collection map(Collection col,unop op)
{
std::transform(col.begin(),col.end(),col.begin(),op);
return col;
}
//transform实现reduce
//这里的参数是复制过来的,所以在函数里面修改col容器,并不影响原始数据;
template <typename Collection,typename binop>
auto reduce(Collection col,binop op)
{
//Collection result(col.size());
std::transform(col.begin(),col.end()-1,col.begin()+1,col.begin()+1,op);
return *(col.end()-1);
}
//zip操作表示对两个容器中对应元素执行操作,结果返回;
template <typename Collection,typename binop>
Collection zip(Collection fc,Collection sc,binop op)
{
//Collection result(fc.size());
std::transform(fc.begin(),fc.end(),sc.begin(),fc.begin(),op);
return fc;
}
// exists 表示判断集合中是否有某个元素符合条件;
template <typename Collection,typename Condition>
bool exists(Collection col,Condition con)
{
auto exist = std::find_if(col.begin(),col.end(),con);
return exist != col.end();
}
//和map()类似,filter()也接收一个函数和一个序列。
//和map()不同的是,filter()把传入的函数依次作用于每个元素,
//然后根据返回值是True还是False决定保留还是丢弃该元素。
template <typename Collection,typename Predicate>
Collection filterNot(Collection col,Predicate predicate )
{
auto returnIterator = std::remove_if(col.begin(),col.end(),predicate);
col.erase(returnIterator,std::end(col));
return col;
}
template <typename Collection,typename Predicate>
Collection filter(Collection col,Predicate predicate)
{
auto fnCol = filterNot(col,[predicate](typename Collection::value_type i) { return !predicate(i);});
return fnCol;
}
int main()
{
//helper println
auto println = [](const char *message){ std::cout << message << std::endl;};
auto lambda_echo = [](int i ) { std::cout << i << std::endl; };
std::vector<int> col{20,24,37,42,23,45,37};
//用for_each来对容器中每个元素进行输出;
println("running foreach");
for_each(col,lambda_echo);
// 用map来对vector中每个元素+1
println("running map operation");
auto addOne = [] (int i) { return i+1;};
auto returnCol = map(col,addOne);
for_each(returnCol,lambda_echo);
//这里用reduce来认为vector每一位是一个大数 ;
println("running reduce operation");
auto reduceAdd = [] (int a, int b){ return a+b;};
int bigNum = reduce(col,reduceAdd);
cout<<"reduce add result:"<<bigNum<<endl;
for_each(col,lambda_echo);
// 这里其实不是真正的zip函数,可以实现两个集合之间的对应元素的同操作;
println("running zip operation");
auto zipAdd = [] (int a, int b){ return a+b;};
std::vector<int> secondCol{40,22,22,24,23,45,34};
auto zipCol = zip(col,secondCol,zipAdd);
for_each(zipCol,lambda_echo);
println("runnig exists");
//prints 1 if true 0 if false
std::cout << "value 20 exist= " << exists(col, [] (int value){ return value==20;}) << std::endl;
std::cout << "value 43 exist= " << exists(col, [] (int value){ return value==43;}) << std::endl;
println("running filterNot");
auto filterCol = filterNot(col,[](int value){ return value==23;});
for_each(filterCol,lambda_echo);
println("running filter");
auto filteredCol = filter(col,[](int value){ return value > 30;});
for_each(filteredCol,lambda_echo);
}