2010-03-14 104 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]