摘要:迭代方法是指接受針對數(shù)組的每個項運行的函數(shù)。值是強制轉(zhuǎn)換為布爾值時計算為的任何值。值得注意的是,這個數(shù)組是不變。由于布爾值只有和,這意味著很容易翻轉(zhuǎn)謂詞的值。檢查數(shù)組的每個成員是否傳遞謂詞,而檢查數(shù)組的成員是否通過謂詞。
.filter是一個內(nèi)置的數(shù)組迭代方法,它接受一個“謂詞(譯者注: 指代一個過濾條件的函數(shù))”,該“謂詞”針對每個值進行調(diào)用,并返回一個符合該條件(“truthy值”)的數(shù)組。
上面那句話包含了很多信息,讓我們來逐一解答一下。
“內(nèi)置”只是意味著它是語言的一部分 - 您不需要添加任何庫來訪問此功能。
“迭代方法”是指接受針對數(shù)組的每個項運行的函數(shù)。.map和.reduce都是迭代方法的示例。
“謂詞”是指.fiflter中接受的的函數(shù)。
“truthy值”是強制轉(zhuǎn)換為布爾值時計算為true的任何值。幾乎所有值都是真實的,除了:undefined,null,false,0,NaN或“”(空字符串)。
讓我們來看看下面這個例子,看一下.filter是怎么運行的。
const restaurants = [ { name: "Dan"s Hamburgers", price: "Cheap", cuisine: "Burger", }, { name: "Austin"s Pizza", price: "Cheap", cuisine: "Pizza", }, { name: "Via 313", price: "Moderate", cuisine: "Pizza", }, { name: "Bufalina", price: "Expensive", cuisine: "Pizza", }, { name: "P. Terry"s", price: "Cheap", cuisine: "Burger", }, { name: "Hopdoddy", price: "Expensive", cuisine: "Burger", }, { name: "Whataburger", price: "Moderate", cuisine: "Burger", }, { name: "Chuy"s", cuisine: "Tex-Mex", price: "Moderate", }, { name: "Taquerias Arandina", cuisine: "Tex-Mex", price: "Cheap", }, { name: "El Alma", cuisine: "Tex-Mex", price: "Expensive", }, { name: "Maudie"s", cuisine: "Tex-Mex", price: "Moderate", }, ];
這是很多信息。我現(xiàn)在想要一個漢堡,所以讓我們過濾掉一下這個數(shù)組。
const isBurger = ({cuisine}) => cuisine === "Burger"; const burgerJoints = restaurants.filter(isBurger);
isBurger是謂詞,而burgerJoints是new數(shù)組,它是餐館的子集。值得注意的是,restaurants 這個數(shù)組是不變。
下面是兩個正在呈現(xiàn)的列表的簡單示例 - 一個原始的餐館數(shù)組,以及一個過濾的burgerJoints數(shù)組。
See the Pen .filter - isBurger by Adam Giese (@AdamGiese) on CodePen.
否定謂詞對于每個謂詞,都有一個相反的否定謂詞。
謂詞是一個返回布爾值的函數(shù)。由于布爾值只有true 和 false,這意味著很容易“翻轉(zhuǎn)”謂詞的值。
我吃了漢堡已經(jīng)過了幾個小時,現(xiàn)在又餓了。這一次,我想過濾out漢堡嘗試新的東西。一種選擇是從頭開始編寫新的isNotBurger謂詞。
const isBurger = ({cuisine}) => cuisine === "Burger"; const isNotBurger = ({cuisine}) => cuisine !== "Burger";
但是,請查看兩個謂詞之間的相似程度。這不是 DRY code。另一種選擇是調(diào)用isBurger謂詞并翻轉(zhuǎn)結(jié)果。
const isBurger = ({cuisine}) => cuisine === "Burger"; const isNotBurger = restaurant => !isBurger(restaurant);
這個更好!如果漢堡的定義發(fā)生變化,您只需要在一個地方更改邏輯。但是,如果我們想要一些否定的謂詞呢?由于這是我們可能經(jīng)常想要做的事情,因此編寫否定函數(shù)可能是個好主意。
const negate = predicate => function() { return !predicate.apply(null, arguments); } const isBurger = ({cuisine}) => cuisine === "Burger"; const isNotBurger = negate(isBurger); const isPizza = ({cuisine}) => cuisine === "Pizza"; const isNotPizza = negate(isPizza);
你可能有一些問題。
什么是.apply?MDN:
apply()方法調(diào)用具有給定this的函數(shù),并將參數(shù)作為數(shù)組(或類數(shù)組對象)提供。什么是arguments?
MDN:
arguments對象是所有(非箭頭)函數(shù)中可用的局部變量。您可以使用參數(shù)在函數(shù)內(nèi)引用函數(shù)的參數(shù)object.為什么要使用舊的function,而不使用更酷的箭頭函數(shù)?
在這種情況下,使用傳統(tǒng)函數(shù)是必要的,因為arguments對象在傳統(tǒng)函數(shù)上是_唯一_可用的。
到2018年8月20日。正如一些評論家所正確指出的那樣, 你可以使用rest參數(shù)用[箭頭函數(shù)寫 negate ](https://css-tricks.com/level-...。
返回謂詞正如我們在使用negate函數(shù)看到的那樣,函數(shù)很容易在JavaScript中返回一個新函數(shù)。這對于編寫“謂詞”非常有用。例如,讓我們回顧一下我們的isBurger和isPizza謂詞。
const isBurger = ({cuisine}) => cuisine === "Burger"; const isPizza = ({cuisine}) => cuisine === "Pizza";
這兩個謂詞具有相同的邏輯;他們只是在比較上有所不同。因此,我們可以將共享邏輯包裝在isCuisine函數(shù)中。
const isCuisine = comparison => ({cuisine}) => cuisine === comparison; const isBurger = isCuisine("Burger"); const isPizza = isCuisine("Pizza");
現(xiàn)在,如果我們想開始檢查價格怎么辦?
const isPrice = comparison => ({price}) => price === comparison; const isCheap = isPrice("Cheap"); const isExpensive = isPrice("Expensive");
現(xiàn)在isCheap和isExpensive 都是DRY(譯者注:Don"t repeat yourself ,一種編程原則,不也要寫重復(fù)的代碼),isPizza和isBurger都是DRY,但isPrice和isCuisine可以公用他們的邏輯!
const isKeyEqualToValue = key => value => object => object[key] === value; // these can be rewritten const isCuisine = isKeyEqualToValue("cuisine"); const isPrice = isKeyEqualToValue("price"); // these don"t need to change const isBurger = isCuisine("Burger"); const isPizza = isCuisine("Pizza"); const isCheap = isPrice("Cheap"); const isExpensive = isPrice("Expensive");
對我來說,這就是箭頭功能之美。在一行中,您可以優(yōu)雅地創(chuàng)建三階函數(shù)。
看看從原始餐館陣列創(chuàng)建多個篩選列表是多么容易?
See the Pen .filter - returning predicates by Adam Giese (@AdamGiese) on CodePen.
撰寫謂詞我們現(xiàn)在可以通過漢堡或廉價的價格過濾我們的陣列......但是如果你想要cheap burgers怎么辦?一種選擇是將兩個過濾器鏈接在一起。
const cheapBurgers = restaurants.filter(isCheap).filter(isBurger);
另一個選擇是將兩個謂詞“組合”成一個謂詞。
const isCheapBurger = restaurant => isCheap(restaurant) && isBurger(restaurant); const isCheapPizza = restaurant => isCheap(restaurant) && isPizza(restaurant);
看看所有重復(fù)的代碼。我們絕對可以將它包裝成一個新功能!
const both = (predicate1, predicate2) => value => predicate1(value) && predicate2(value); const isCheapBurger = both(isCheap, isBurger); const isCheapPizza = both(isCheap, isPizza); const cheapBurgers = restaurants.filter(isCheapBurger); const cheapPizza = restaurants.filter(isCheapPizza);
如果你沒有披薩或漢堡包怎么辦?
const either = (predicate1, predicate2) => value => predicate1(value) || predicate2(value); const isDelicious = either(isBurger, isPizza); const deliciousFood = restaurants.filter(isDelicious);
這是朝著正確方向邁出的一步,但是如果您想要包含兩種以上的食物呢?這不是一種可擴展的方法。有兩種內(nèi)置的數(shù)組方法在這里派上用場。.every和.some都是謂詞方法,也接受謂詞。.every檢查數(shù)組的每個成員是否傳遞謂詞,而.some檢查數(shù)組的any成員是否通過謂詞。
const isDelicious = restaurant => [isPizza, isBurger, isBbq].some(predicate => predicate(restaurant)); const isCheapAndDelicious = restaurant => [isDelicious, isCheap].every(predicate => predicate(restaurant));
并且,像往常一樣,讓我們??將它們包裝成一些有用的抽象。
const isEvery = predicates => value => predicates.every(predicate => predicate(value)); const isAny = predicates => value => predicates.some(predicate => predicate(value)); const isDelicious = isAny([isBurger, isPizza, isBbq]); const isCheapAndDelicious = isEvery([isCheap, isDelicious]);
isEvery和isAny都接受一個謂詞數(shù)組并返回一個謂詞。
由于所有這些謂詞都可以通過高階函數(shù)輕松創(chuàng)建,因此根據(jù)用戶的交互創(chuàng)建和應(yīng)用這些謂詞并不困難。綜合我們學(xué)到的所有課程,這里是一個應(yīng)用程序示例,通過應(yīng)用基于按鈕點擊的過濾器來搜索餐館。
See the Pen .filter - dynamic filters by Adam Giese (@AdamGiese) on CodePen.
總結(jié)
過濾器是JavaScript開發(fā)的重要組成部分。無論您是從API響應(yīng)中挑選出錯誤數(shù)據(jù)還是響應(yīng)用戶交互,您都會無數(shù)次想要數(shù)組值的子集。我希望這個概述有助于您可以操作謂詞來編寫更易讀和可維護的代碼。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/52953.html
摘要:迭代方法是指接受針對數(shù)組的每個項運行的函數(shù)。值是強制轉(zhuǎn)換為布爾值時計算為的任何值。值得注意的是,這個數(shù)組是不變。由于布爾值只有和,這意味著很容易翻轉(zhuǎn)謂詞的值。檢查數(shù)組的每個成員是否傳遞謂詞,而檢查數(shù)組的成員是否通過謂詞。 .filter是一個內(nèi)置的數(shù)組迭代方法,它接受一個謂詞(譯者注: 指代一個過濾條件的函數(shù)),該謂詞針對每個值進行調(diào)用,并返回一個符合該條件(truthy值)的數(shù)組。 ...
摘要:數(shù)組方法全解析包含數(shù)組自帶屬性返回創(chuàng)建數(shù)組對象的原型函數(shù)返回數(shù)組對象的長度這個是老熟人了,可以增加數(shù)組的原型方法和屬性,這個放在后面的繼承中講數(shù)組的方法首先讓我們看看數(shù)組的對象屬性。 Javascript 數(shù)組方法全解析(包含es6) 1. 數(shù)組自帶屬性 constructor //返回創(chuàng)建數(shù)組對象的原型函數(shù) length //返回數(shù)組對象的長度 prototype //這個是老...
摘要:最后,客戶端只是依賴于引擎的環(huán)境之一。新的編譯器管道利用來實現(xiàn),并生成可以轉(zhuǎn)換生成器控制流到簡單的本地控制流的字節(jié)碼??梢愿菀椎貎?yōu)化所得到的字節(jié)碼,因為它不需要知道關(guān)于生成器控制流的任何具體內(nèi)容,只是如何保存和恢復(fù)函數(shù)的狀態(tài)。 本文轉(zhuǎn)載自:眾成翻譯譯者:smartsrh鏈接:http://www.zcfy.cc/article/2978原文:https://v8project.blo...
摘要:正則表達式實現(xiàn)快速古詩匹配作者簡介是推出的一個天挑戰(zhàn)。數(shù)據(jù)匹配操作使用基礎(chǔ)參考文檔項目源碼分析正則找出匹配的詩句替換高亮的標(biāo)簽構(gòu)造值會返回帶搜索關(guān)鍵字的新數(shù)組。執(zhí)行對大小寫不敏感的匹配。 Day06 - Fetch、filter、正則表達式實現(xiàn)快速古詩匹配 作者:?liyuechun 簡介:JavaScript30 是 Wes Bos 推出的一個 30 天挑戰(zhàn)。項目免費提供了 30 ...
閱讀 2765·2023-04-25 14:15
閱讀 2708·2021-11-04 16:11
閱讀 3399·2021-10-14 09:42
閱讀 448·2019-08-30 15:52
閱讀 2830·2019-08-30 14:03
閱讀 3550·2019-08-30 13:00
閱讀 2117·2019-08-26 11:40
閱讀 3312·2019-08-26 10:25