2010-03-14 39 views
13

作为跨过一系列对象的最小/最大值的延续,我想知道过滤器vs地图的性能比较。Javascript过滤器vs地图问题

因此,我将我的代码中的值放在一起进行测试,以查看FireBug中的结果。

这是代码:

var _vec = this.vec; 
min_x = Math.min.apply(Math, _vec.filter(function(el){ return el["x"]; })); 
min_y = Math.min.apply(Math, _vec.map(function(el){ return el["x"]; })); 

map PED版本返回正确的结果。然而filter ed版本返回NaN。打破它,逐步审查并最终检查结果,看起来内函数返回属性_vec,但从filter返回的实际数组是未经过滤的_vec

我相信我的使用filter是正确的 - 任何人都可以看到我的问题吗?

这里有一个简单的测试:

<!DOCTYPE html> 
<html lang="en"> 
<head> 
<meta http-equiv="content-type" content="text/html; charset=utf-8" /> 
<title>S:GTC Map Test</title> 
</head> 
<body> 
<script type="text/javascript"> 
function vector(x,y,z) { this.x = x; this.y =y; this.z=z; } 
var vec = []; 
vec.push(new vector(1,1,1)); 
vec.push(new vector(2,2,2)); 
vec.push(new vector(2,3,3)); 
var _vec = vec; 
min_x = Math.min.apply(Math, _vec.filter(function(el){ return el["x"]; })); 
min_y = Math.min.apply(Math, _vec.map(function(el){ return el["x"]; })); 

document.write("<br>filter = " + min_x); 
document.write("<br>map = " + min_y); 
</script> 
</body> 
</html> 

回答

34

否,filter方法不返回unfiletered阵列。它返回一个包含内部函数返回true的项的数组。

由于您没有从内部函数返回布尔值,因此将该值转换为布尔值,因此对象引用将转换为true。因此,它返回一个包含原始数组中所有项目的新数组。

filter方法与map方法不同。 map方法用于转换数组中的每个项目,而filter方法用于选择数组中的某些项目。比较这些方法之间的性能是没有意义的,因为只有其中一个做你想做的事情。

+2

稀释。看来我误解了过滤功能的工作原理。我的印象是它将一个修改后的对象返回给一个数组。 – 2010-03-14 16:50:07

4

引自:

JavaScript权威指南
由David那根

地图()

map()方法传递其所是 阵列的每个元件调用到您指定的函数,并返回一个包含该函数返回值的数组 。

例如:

a = [1, 2, 3]; 

b = a.map(function(x) { return x*x; }); // b is [1, 4, 9] 

传递给映射()函数以相同的方式被调用作为 函数传递到的forEach()。但是,对于map()方法,您传递的 函数应该返回一个值。请注意,map()会返回一个新的 数组:它不会修改它所调用的数组。如果该数组是 稀疏,则返回的数组将以同样的方式稀疏:它将具有相同的长度和相同的缺失元素,即 。

滤波器()

方法返回包含 阵列上调用它的元件的子集的阵列。您传递给它的函数应该是 predicate:一个返回true或false的函数。谓词 与forEach()和map()一样被调用。如果返回值为真, 或转换为true的值,则传递给 谓词的元素是该子集的成员,并被添加到 将成为返回值的数组中。

实例:

a = [5, 4, 3, 2, 1]; 

smallvalues = a.filter(function(x) { return x < 3 }); // [2, 1] 

everyother = a.filter(function(x,i) { return i%2==0 }); // [5, 3, 1]