JavaScript >> Javascript 文檔 >  >> JavaScript

JavaScript 的 filter() 方法指南

簡介

過濾信息是我們使用自動化/計算機最重要的任務之一!如果我們必須手動篩選所有內容,計算機和軟件就不會那麼有用了。通過擴展 - 為最終用戶過濾數據是一項常見任務,允許用戶將搜索空間縮小到可管理的水平。 JavaScript 是世界領先的前端語言,也是最終用戶看到的第一個前沿語言。不用說,使用 JavaScript 進行過濾的重要性怎麼強調都不為過。

在 JavaScript 中,filter() 方法允許我們過濾數組 - 迭代現有值,並僅將符合特定條件的值返回到新數組中。

filter() 函數針對數組中的每個條目運行條件表達式。如果此條件計算結果為 true ,元素被添加到輸出數組中。如果條件失敗,則不將元素添加到輸出數組中。

語法和參數值

語法很簡單:

const filteredArray = oldArray.filter(callbackFn(element, index, array), context)

callbackFn 可以是任何任意函數/謂詞/條件,只要它返回一個布爾值,基於 element 的值 . 技術上 ,它不必使用 element 在它的計算中,但這很可能不是一個非常有用的過濾函數。

indexarray 是可選的,您不太可能需要使用 array 在實踐中。 index 是當前項的索引,array 是指向原始數組的指針。

注意: filter 函數構造一個新數組並返回滿足回調中給定條件的所有對象。它不會改變底層的原始數組。

JavaScript 的 filter() 作品

我們來看看filter() 方法在行動。在 JS 的早期版本中,在 ES6 之前 - 回調函數將用作:

const numbers = [20, 40, 17, 99, 59, 77];
const filteredNumbers = numbers.filter(function (number) {
    return number > 20;
});
  
console.log(filteredNumbers); // [40,99,59,77]

從 ES6 開始,我們可以將其簡化為 箭頭函數

const numbers = [20, 40, 17, 99, 59, 77];
const filteredNumbers = numbers.filter((number) => {
    return number > 20;
});
  
console.log(filteredNumbers); // [40,99,59,77]

或者,您可以將函數折疊為:

const numbers = [20, 40, 17, 99, 59, 77];
const filteredNumbers = numbers.filter((number) => number > 20);
console.log(filteredNumbers); // [40,99,59,77]

如何使用上下文 帶有 filter() 的對象

filter() 方法可以接受一個額外的、可選的 context 對象:

filter(callbackfn, contextobj);

可以使用 this 引用該對象 回調中的關鍵字和 context 表示,嗯,我們作為 上下文 傳入的任何內容 為過濾器。我們來看一個例子!

我們將通過 menu 進行排序 列表,刪除價格不在 15 到 25 之間的所有商品。價格範圍是一個單獨的對象,我們將其傳遞到 filter() 作為上下文 .從某種意義上說——它通常用於定義一個“配置”對象,包含我們可以通用訪問的值,而無需對它們進行硬編碼:

const menu = [
    {
        name: "buttermilk pancakes",
        price: 15.99
    },
    {
        name: "diner double",
        price: 13.99
    },
    {
        name: "godzilla milkshake",
        price: 6.99
    },
    {
        name: "country delight",
        price: 20.99
    },
    {
        name: "egg attack",
        price: 22.99
    }
];
  
let priceRange = {
    lower: 15,
    upper: 25
};

現在,讓我們 filter() menu 列表,傳入 priceRange 作為 context

let filteredMenu = menu.filter(function (menu) {
    return menu.price >= this.lower && menu.price <= this.upper;
}, priceRange);
  
console.log(filteredMenu);

這導致:

[
    {
        name:"buttermilk pancakes",
        price:15.99
    },
    {
        name:"country delight",
        price:20.99
    },
    {
        name:"egg attack",
        price:22.99
    }
]

如何使用索引 參數

index 可用於評估元素在原始數組中的位置。例如,我們可以按元素的位置進行過濾:

const users = ["John", "Doe", "Stephen", "Matt", "Abigail", "Susu"];
  
const topThree = users.filter((element, index) => {
    return index <= 2;
});

console.log(topThree); // ["John", "Doe", "Stephen"]

雖然這也可以通過訪問 最後 N 個元素來實現 在數組中,索引可以扮演其他角色,而不是唯一的過濾條件。

如何使用數組 參數

array 參數引用我們過濾的原始數組。由於無論如何您都在遍歷數組,因此您通常會在不使用 array 的情況下感到滿意 參數,但如果邏輯依賴於數組本身的某些狀態或屬性,它會很有用:

const competitors = ["John", "Doe", "Stephen", "Matt", "Abigail", "Susu"];
  
function selectWinners(name, index, array) {
   
    if (array.length > 3 && name.includes('a')) {
        return true;
    } else {
      return false;
    }
}
  
let lselectLoosers = competitors.filter((name, index, array) =>
    selectWinners(name, index, array)
);

console.log(lselectLoosers); // ["Matt", "Abigail", "Susu"]

另一個例子可能是如果我們想獲得一個數組的一半元素。這種情況下,我們可以使用原始數組獲取總元素,根據索引值過濾元素:

const halfArray = function (element, index, array) {
    const half = Math.floor(array.length / 2);
    return index < half;
};

我們現在可以使用 halfArray 進行過濾 :

const names = ["John", "Doe", "Stephen", "Matt", "Abigail", "Susu"];
const halfNames = names.filter(halfArray);
console.log(halfNames); // ["John", "Doe", "Stephen"]

總之 - filter() 方法接受一個謂詞函數,該函數針對數組中的每個元素運行。基於布爾返回值,element 被放置或未放置在新的輸出數組中。

在迭代結束時 - 僅返回結果新數組,由謂詞函數中定義的條件過濾。 context object 可以傳入,並且通常用於定義一個“配置”對象,該對象存儲過濾期間使用的動態值。 index 指的是當前元素在原數組中的位置,array 是對原始數組的引用。

JavaScript 的 filter() 示例

隨著介紹的結束 - 讓我們深入了解 filter() 的一些實際示例 方法。

按值過濾對像數組

通過對象包含的某個值過濾對像數組是 filter() 最常見的應用之一 方法。

處理對象與處理其他類型的數據類型沒有太大區別!

免費電子書:Git Essentials

查看我們的 Git 學習實踐指南,其中包含最佳實踐、行業認可的標準以及隨附的備忘單。停止谷歌搜索 Git 命令並真正學習 它!

例如,假設我們有一個 student 數組 對象,有幾個字段。假設您還想按當年畢業的學生篩選學生 - new Date().getFullYear() 獲得的學生 .

您可以輕鬆比較 graduationYear 每個 element 到當年:

const students = [
    { firstName: "John", lastName: "Doe", graduationYear : 2022 },
    { firstName: "Stephen", lastName: "Matt", graduationYear : 2023 },
    { firstName: "Abigail", lastName: "Susu", graduationYear : 2022 }
];

const currentYear = new Date().getFullYear();

let graduatingStudents = students.filter((element) => {
    if (element.graduationYear === currentYear) {
        return element;
    }
});
  
console.log(graduatingStudents);

這導致:

[
    {
        firstName:"John",
        lastName:"Doe",
        graduationYear:2022
    },
    {
        firstName:"Abigail",
        lastName:"Susu",
        graduationYear:2022
    }
]
在 JavaScript 中使用數組過濾器過濾素數

讓我們繼續一個簡單的練習——過濾素數!讓我們用一組整數定義一個列表,然後 filter() 它:

const myArray = [-7, -5, -2, 2, 1, 3, 12, 14, 13, 15, 70, 17, 33, 25, 27, 30, 97];
      
const primeNumbers = myArray.filter((element) => {
    for (let i = 2; element > i; i++) {
        if (element % i === 0) {
          return false;
        }
    }
    return element > 1;
});
  
console.log(primeNumbers); // [2, 3, 13, 17, 97]

當然,你也可以定義一個 primeNumbers() 函數,它接受一個元素並返回 truefalse 根據元素是否為素數,然後在 filter() 中使用該方法 調用,如果你要多次調用它:

const numbers = [-7, -5, -2, 2, 1, 3, 12, 14, 13, 15, 70, 17, 33, 25, 27, 30, 97];

function findPrimeNumbers(element) {
    for (let i = 2; element > i; i++) {
        if (element % i === 0) {
          return false;
        }
    }
    return element > 1;
}

console.log(numbers.filter(findPrimeNumbers)); // [2, 3, 13, 17, 97]
如何過濾數組中的數字

過濾掉數組中其他元素之間的數字,就像檢查變量是否為數字並返回布爾值一樣簡單:

const isNumber = function (element) {
    return Number.isFinite(element);
};

我們現在可以使用可重用函數調用我們的過濾器方法:

const random = ['1', 'blue', 2, '-4', 0, true, -3.4 ];
const numbers = random.filter(isNumber);
console.log(numbers); // [2, 0, -3.4]

上面的方法對於表示字符串的數字沒有用,因此另一種方法可能是首先將元素轉換為數字(如果適用)(parseFloat() ) 並使用 Number.isFinite() 檢查轉換後的值 :

const isNumber = function (element) {
    return Number.isFinite(parseFloat(element));
};

const random = ['1', 'blue', 2, '-4', 0, true, -3.4 ];
const numbers = random.filter(isNumber);        
console.log(numbers); // ["1", 2, "-4", 0, -3.4]

filter() vs find() 數組方法

值得花點時間欣賞一下 filter() 用於和不用於什麼。 過濾列表 基於一個或多個標准通常包括返回一個子列表 ,符合標準 - 如果標準非常嚴格,則更罕見的是單個元素。當您尋找元素時 在一個列表中 - 你會過濾掉 一切 除了目標元素,以列表形式返回。更適合後者的是 find() 元素,而不是 filter() 一個列表。

  • filter() 返回“通過”謂詞的所有元素的列表
  • find() 返回“通過”謂詞的第一個對象

假設您有一組具有不同類別的菜單:

  const menu = [
    {
      name: "buttermilk pancakes",
      category: "breakfast",
      price: 15.99,
      status: "available"
    },
    {
      name: "diner double",
      category: "lunch",
      price: 13.99,
      status: "available"
    },
    {
      name: "godzilla milkshake",
      category: "shakes",
      price: 6.99,
      status: "available"
    },
    {
      name: "country delight",
      category: "breakfast",
      price: 20.99,
      status: "86"
    },
    {
      name: "egg attack",
      category: "lunch",
      price: 22.99,
      status: "available"
    }
  ];

現在是上午 8 點,餐廳只供應早餐食品,直到上午 10 點。您需要過濾掉非早餐項目:

let breakfastMenu = menu.filter((menu) => menu.category === "breakfast");  
console.log(breakfastMenu);

這導致:

[
    {
        name:"buttermilk pancakes",
        category:"breakfast",
        price:15.99,
        status:"available"
    },
    {
        name:"country delight",
        category:"breakfast",
        price:20.99,
        status:"86"
    }
]

現在,假設有人要訂購“鄉村美食” .子列表很短,足以讓我們注意到它是 86'd,但列表更長 - 我們可能想要檢查該項目在找到時是否可用:

const delight = menu.find((menu) => menu.name === "country delight");

if (delight.status !== "86") {
    console.log('Available!');
} else {
    console.log('Sorry, the item is not available :(');
}

這導致:

Sorry, the item is not available :(

使用 filter()map()

map() 方法用於遍歷數組,並對每個元素應用一個函數,將結果返回到一個新數組。這是一個非常常見的方法,並與 filter() 鏈接 出色地!例如,讓我們過濾掉一些學生,然後將元素映射到他們的姓名和姓氏:

const students = [
    { firstName: "John", lastName: "Doe", grduationYear: 2022 },
    { firstName: "Stephen", lastName: "Matt", grduationYear: 2023 },
    { firstName: "Abigail", lastName: "Susu", grduationYear: 2022 }
];
  
let graduatingStudents = students
    .filter((element) => element.grduationYear === new Date().getFullYear())
    .map((item) => {
      return `${item.firstName} ${item.lastName}`;
});
  
console.log(graduatingStudents); // ["John Doe", "Abigail Susu"]

使用 filter() indexOf()

indexOf() 方法可用於檢查字符串是否以子字符串開頭,並根據是否有條件返回元素。例如,我們可以根據它們是否以 "mth" 開頭來過濾掉一個科學課程列表 ,表示這些是數學課程

let sciCourses = ["Mth101", "Chm201", "Bio301", "Mth203", "Mth205"];
function checkCourses(courseArray, searchText) {
    return courseArray.filter(function (item) {
        return item.toLowerCase().indexOf(searchText.toLowerCase()) !== -1;
    });
}
console.log(checkCourses(sciCourses, "mth")); // ["Mth101", "Mth203", "Mth205"]

注意: 同樣,由於 filter() 方法不會改變原始數組,我們需要保存過濾後的數組以供以後使用。

結論

在本指南中,我們了解了 JavaScript 的 filter() 方法有效,以及在給定謂詞/某些過濾條件的情況下,我們如何使用它來過濾數組中的元素。我們已經查看了隨附的參數,例如 context , indexarray 允許您更改謂詞邏輯。

最後,我們查看了幾個示例,並涵蓋了 find() 作為僅搜索單個元素的替代方法,以及如何使用 filter() 可以與鏈中的其他方法一起使用。


Tutorial JavaScript 教程
  1. 在 NodeJS 中生成 JSON Web Token (JWT)

  2. 在 VueJS 中為每個選中的複選框創建一個容器

  3. jQuery 選擇插件

  4. 模仿貓與參考貓

  5. 如何設置 Leaflet Map 的縮放以顯示 React Leaflet 中的所有標記?

  6. 使用動態鍵訪問 Javascript 對象值

  7. Nodejs 無法從 html 參考中找到圖像

  1. 在 EventEmitter 上,我如何知道我可以收聽的所有事件?

  2. 函數式編程:在原型上實現過濾器方法

  3. 一個巧妙的 JavaScript 小技巧 indexOf()

  4. Vuejs中的單獨數組推送

  5. 如何在沒有 bootstrap-vue 的情況下在 vue.js 2 中使用 bootstrap 4?

  6. React Refs:完整的故事

  7. 查找 id 以公共字符串開頭的所有元素

  1. 你應該在 2021 年學習 jQuery 嗎?

  2. 使用我們的新 JavaScript 編輯器編寫更多代碼並創建可重用函數

  3. 鼠標懸停的 IMDB 評級 - II

  4. 如何使用 Go 文本模板