从Map和Reduce说起

来源:互联网 发布:客服源码 编辑:程序博客网 时间:2024/04/28 23:28

从Map和Reduce说起

最近在看函数式编程的一些东西,尤其是Sheme和Python,有些困惑,遂写下一些东西。
在Python中,map/reduce/filter是函数式编程的一组重要的工具. map将过程(函数)应用于数据以产生新的数据,而reduce则是将数据进行归并. 下面的语句分别完成将List中每个元素平方的功能和对List求和的功能:
>>> map(lambda x: x*x,[1,2,3,4,5])
[1, 4, 9, 16, 25]
>>> reduce((lambda x,y:x+y),[1,2,3,4,5])
15
map将过程x*x应用于list中的每个元素,并产生新的list作为返回值,而reduce每次将 list中当前元素与上次应用过程的结果作为输入应用到过程中. 看一个复杂的例子,用于求前10个Fibobacci数:
map(lambda x,f=lambda x,f:(x<=1) or (f(x-1,f)+f(x-2,f)): f(x,f),range(10))
 
Map与Reduce在Scheme/Lisp中就已经流行,Scheme中的Map实现为:
(define (map proc items)
   (if (null? items)
       (list )
       (cons (proc (car items)) (map proc (cdr items)))))

(define (reduce proc items)
  (if (null? items)
      0
      (proc (car items) (reduce proc (cdr items)))))
根据上面的map/reduce的定义,下面的表达式用于求1-5的平方和
(reduce (lambda (x y) (+ x y)) (map (lambda(x) (* x x)) (list 1 2 3 4 5)))
 
通过Map和Reduce建立了一种处理表的高层抽象.与命令式语言相比,Scheme等函数式语言将处理数据的逻辑与提取元素的细节隔离开。(From: SICP)
在C/C++中也可以用函数指针来实现函数式编程的概念,但是由于语言特性的不支持,所以代码相当的晦涩,远不如Python中的优雅自然.
#include<stdio.h>

typedef int(*function)(int);
typedef int(*reduceFunc)(int,int);

int square(int i)
{
return i*i;
}

int multiply(int i)
{
return 2*i;
}

int add(int i, int j)
{
return i + j;
}

int map(function func,int* list,int len)
{
for(int i=0;i<len; i++)
  list[i] = func(list[i]);
return len;
}

int reduce(reduceFunc func,int* list,int len)
{
if(len<=0)
  return -1;
int retVal = list[0];
for(int i=1; i<len; i++)
  retVal = func(list[i],retVal);

return retVal;
}

int main(int argc, char** argv)
{
int intArray[5];
for(int i=0;i<5;i++)
{
  intArray[i] = i+1;
}

function funcPointer = (function)&square;
map(funcPointer,intArray,5);
for(int i=0;i<5; i++)
{
  printf("intArray[i]:%d/n ",intArray[i]);
}

funcPointer = (function)&multiply;
map(funcPointer,intArray,5);
for(int i=0;i<5; i++)
{
  printf("intArray[i]:%d/n ",intArray[i]);
}

int reduceArray[] = {8,7,2,-17,5,-5};
reduceFunc reduceFp = (reduceFunc)&add;
int reduceValue = reduce(reduceFp,reduceArray,6);
printf("reduceValue: %d/n",reduceValue);
}
Gooogle的工程师们根据Map/Reduce的思想,实现了一种分布式调度算法MapReduce,其核心是利用一个Map操作以 Key/Value对作为输入,并且产生一组中间key/Value集合。Reduce方法接收一个中间的键I和一组关于该键的值,然后将该将这些值合并 成一组更小的集合.
相关链接:
Microsoft F#: http://research.microsoft.com/fsharp/fsharp.aspx
MapReduce: http://labs.google.com/papers/mapreduce-osdi04.pdf
 
原创粉丝点击