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