JavaScript数组化简方法reduce详解,并比PHP中的array_reduce作一下比较

作者:admin     字体:[增加 减小]    类型:原创
JavaScript中的Array.prototype.reduce()方法在化简数组时可以极大地简化循环体内的代码,如何使用,本文为您娓娓道来。另外,作为一个资深的PHP程序员,本文还为你讲解了与JS中的map方法极为相似的PHP函数array_reduce,并教你如何在ThinkPHP控制器里如何使用。

JavaScript中,Array.prototype.reduce()方法使用指定的迭代函数将数组简化为单一的值。这个方法在数式编程中是常见的操作,也可以称为“注入”和“折叠”。举例说明它是如何工作的:

<script>
var a = [1,2,3,4,5,6,7,8,9];

/*求和*/
var sum = a.reduce(function(v,w){
    return v+w;
},0);   // => 45

/*求积*/
var product = a.reduce(function(v,w){
    return v * w;
},1);   // => 362880

/*求最大值*/
var max = a.reduce(function(v,w){
    return v>w?v:w;
}); //9

//空数组调用reduce,返回初始值
console.log([].reduce(function(v,w){
    return v * w;
},10)); // => 10

//一个元素的数组调用reduce且没有初始值,返回其中的那一个元素
console.log([10].reduce(function(v,w){
    return v * w;
}));    // => 10
</script>

reduce()方法需要两个参数。第一个是执行化简操作的函数。化简函数的任务就是用某种方法把两个值组合或化简为一个值,并返回化简后的值。在上述例子中,函数通过加法、乘法或取最大值的方法组合两个值。第二个(可选)参数是一个传递给函数的初始值。

reduce()方法使用的函数与forEach()和map()使用的函数不同。比较熟悉的是,数组元素的索引和数组本身将作为第二个至第四个参数递给函数。第一个参数是到目前为止的化简操作累积的结果。第一次调用函数时,第一个参数是一个初始值,它就是传递给reduce()的第二个参数。在接下来的调用中,这个值是上一次化简函数的返回值。这种算法与PHP中的array_reduce()函数完全一样,接下来我们还会将它们作一比较。在上面的第一个例子中,第一次调用化简函数时的参数是0和1.将两者相加并返回1。再次调用时的参数是1和2,它返回3。然后它计算3+3=6、6+4=10,最后计算36+9=45。最后的值就是45,并返回。

可能你已经注意到了,上面的第三次调用reduce()时只有一个参数:没有指定初始值。当不指定初始值调用reduce()时,它将使用数组的第一个元素作为其初始值。这意味着第一次调用化简函数就使用了第一个和第二个数组元素作为其第一个和第二个参数。在上面求和与求积的例子中,可以省略初始值参数。

在空数组上,不带初始值参数调用reduce()将导致类型错误异常。如果调用它的时候只有一个值————数组只有一个元素并且没有指定初始值,或者有一个空数组并且指定一个初始值————reduce()只是简单地返回那个值而不会调用化简函数。这个在上例中的第四个与第五个调用中可以看出。

在JavaScript中还有一个方法reduceRight(),它的工作原理和reduce()一样,不同的是它按照数组索引从高到低(从右到左)处理数组,而不是从低到高。

我们把JS中的reduce()方法讲解完了,学过PHP的朋友,肯定会想到与它非常相似的一个函数array_reduce(),二者的功能非常相似。在php5.3版本以前,因为在PHP的类里使用array_reduce,还得 array_reduce($array,array($this,'callback_func'),$initial),因为还要再开销一个函数,所以使用并不是很多,但是在PHP5.3之后,PHP中函数传参可以像JS一样传函数,这样的话,使用array_map()就异常方便了,大家请看下面的例子

$a = array(1,2,3,4,5,6,7,8,9);      
//求和
$sum = array_reduce($a,function($v,$w){
    return $v + $w;         
},0);       
//求积
$product = array_reduce($a,function($v,$w){
    return $v * $w;         
},1);       
//最大值
$max = array_reduce($a,function($v,$w){
    return $v > $w ? $v : $w ;          
});
$test1 = array_reduce(array(),function($v,$w){
    return $v * $w; //以求积作测试,=> NULL
});
$test2 = array_reduce(array(1),function($v,$w){
    return $v * $w; //以求积作测试,=> 0
});
$test3 = array_reduce(array(),function($v,$w){
    return $v * $w; //以求积作测试,=> 1
},1);
P($sum,$product,$max,$test1,$test2,$test3);     
//$this->display();

下面截出的代码,是在ThinkPHP3.1.2版本中的控制器中演示的使用array_reduce()函数的使用方法。

在ThinkPHP中的控制器中如何使用array_reduce函数