2014-08-30 80 views
6

我正在通過JavaScript:權威指南作爲Learn JavaScript Properly的一部分,而我在第7章數組方法部分的filter()方法中遇到了問題。JavaScript filter()方法混淆

這裏所提供的例子:

filter()方法返回包含在其上調用它的陣列的 元件的子集的陣列。您傳遞給 的函數應該是謂詞:返回true或false的函數。與forEach()map()一樣, 謂詞也被調用。如果返回值 值爲true,或者值爲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] 

當我越來越糊塗是i是如何準確地在該everyother線適用於x。這是我認爲正在發生的事情:

  1. i(的a[]指數)正在通過功能,x,其謂語適用於a[]每個元素,並返回[4, 2]通過。

  2. 然後功能說「過濾[4, 2]a[]」...我真的很模糊如何。

當我亂七八糟的控制檯的時候,我已經試過:

everyother = a.filter(function(i) { return i%2==0 }); // returns [4, 2] 

這正是我所期望的,但我不明白在JS如何處理參數時內部發生更改上面的代碼

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

(我知道陣列方法應用於像這樣:function(element, index, array)

對於這個特殊的例子,很明顯,我認爲我能得到預期的結果的另一種方式:

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

但我懷疑這種思維路線恰恰缺少的例子是試圖傳達出點......我只是想念它。

+3

在JavaScript中,參數始終是可選的。過濾器回調的簽名是'fn(element,index,arr)'第一個例子'i'指向元素,在第二個例子中它指向索引。您只是在第二個示例中獲取索引均勻的元素。 – 2014-08-30 18:08:09

+0

我認爲這個例子只是試圖解釋一下,你可以使用數組中的值本身和它的索引作爲謂詞。不清楚什麼不清楚。 – Bergi 2014-08-30 18:12:35

回答

5

當您使用兩個參數調用filter時,第一個參數綁定到數組元素值,第二個參數(可選參數)綁定到元素index。

您的困惑源於輸入數組[5,4,3,2,1]有點特殊 - 具有偶數索引(5,3,1)的元素是奇數,而具有奇數索引(4,2)的元素是偶數。

這使得這個篩選謂詞...%2總是挑選相同「種類」的元素,這取決於你作爲謂詞參數(值或索引)傳遞什麼,你將得到奇數或偶數元素。

我的建議,以清理混亂將是選擇一個不同的陣列來測試你的過濾方法。該陣列應混合使用奇怪的索引和值,如[1,3,4,5,7,8]。您將立即觀察謂詞在考慮值或索引時會發生什麼。

還要記住,當創建一個過濾謂詞時,名稱的形式參數是任意的,重要的是它們的位置。第一個參數,不管你怎麼稱呼它代表價值,第二個代表指數。如果您意外碰撞參數名稱,並且您將第一個參數i和第二個參數i稱爲第二個參數,則它會在兩種情況下綁定到其他參數。 。

+0

啊,只要我讀了你的第二句話就點擊了。我正在用'i'中包含的_value_來代替_value_的位置。謝謝您的幫助。 – benvenker 2014-09-02 23:44:53

7

你舉的例子是非常簡單而明確:

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] 

第一個寫着:»回到我的每一個元素(X),其中較小比3«。結果並不令人震驚。

第二個寫着:»回到我的每一個元素,它的索引(i)爲偶數(含0)«

X只是忽略。

你還可以這樣寫[5, 4, 3, 2, 1].filter(function(_,x){return x%2===0})

MDNArray.prototype.filter()

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

x是陣列中的每個元件(第一次迭代X = 5,第二次迭代X = 4,等等...)
i是索引 - (第一迭代i = 0,第二迭代i = 1,等等..)

因此,在問題中(對於第一次迭代 - i%2變爲0%2,它等於0並且條件變爲真,並且第一個元素返回到數組。 。返回5,)。 接下來,1%2!= 0,所以4被刪除。 2%2 == 0,因此3次停留。 (等等)

在此語法中:-x對每個迭代都有一個值,但它在條件中沒有用完。提示:filter()始終需要一個布爾值。無論返回的是true還是false,都會確定值(或元素)是否保留在數組中。

0

其簡單......在everyotheri是每個元素的i唯一可能的值的指數是0,1,2,3,4,你有array.Now五行出的所有值的i只有0,2,4可以被2整除,這就是爲什麼你得到這些指數的值,即[5,3,1]