Phương thức filter()
dùng để tạo một mảng mới với tất cả các phần tử thỏa điều kiện của một hàm test.
Mã nguồn của ví dụ tương tác này được lưu tại GitHub. Nếu bạn muốn đóng góp cho các ví dụ tương tác này, hãy clone repo https://github.com/mdn/interactive-examples và gửi pull request cho chúng tôi.
Cú pháp
var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])
Tham số
callback
- Đây là hàm thử, dùng để kiểm tra từng phần tử của mảng. Trả về
true
để giữ lại phần tử, hoặcfalse
để loại nó ra. Nó được gọi với ba tham số: -
element
- Phần tử đang được xử lý trong mảng.
index
Optional- Chỉ mục (index) của phần tử đang được xử lý.
array
Optional- Mảng nguồn mà hàm
filter
đang xử lý.
thisArg
Optional- Không bắt buộc. Giá trị của
this
bên trong hàmcallback
.
Giá trị trả về
Một mảng mới với các phần tử đã thỏa điều kiện của hàm test. Nếu không có phần tử nào thỏa điều kiện, một mảng rỗng sẽ được trả về.
Mô tả
filter()
sẽ thực thi hàm callback
trên từng phần tử của mảng, và xây dựng một mảng mới với các phần tử mà giá trị trả về của callback
nếu ép kiểu sẽ mang giá trị true
. callback
chỉ được thực thi tại những chỉ mục (index) của mảng mà chúng được gán giá trị; nó không được thực thi tại chỉ mục đã bị xóa hoặc chưa từng được gán giá trị. Những phần tử không thỏa điều kiện tại hàm thử callback
sẽ bị bỏ qua, không được cho vào mảng mới.
callback
được gọi với ba tham số:
- giá trị của phần tử
- chỉ mục (index) của phần tử
- mảng ban đầu mà hàm thử đang được gọi lên
Nếu tham số thisArg
được truyền cho hàm filter
, nó sẽ được thay vào giá trị của từ khóa this
trong hàm callback. Nếu không, giá trị undefined
sẽ được dùng cho this
. Tóm lại, giá trị của từ khóa this
trong hàm callback
được xác định tuân theo các quy tắc thông thường để xác định this
trong một hàm.
filter()
không làm thay đổi mảng mà nó được gọi.
Các phần tử được filter()
chạy qua được xác định từ đầu trước khi callback
được gọi lần đầu tiên. Những phần tử mới được thêm vào sau khi filter()
bắt đầu chạy sẽ không được truyền vào callback
. Trong lúc filter()
đang chạy, nếu những phần tử hiện tại của mảng bị thay đổi, thì giá trị của chúng khi được truyền cho callback
là giá trị tại thời điểm filter()
chạy qua; những phần tử đã xóa sẽ bị bỏ qua.
Ví dụ
Lọc bỏ các giá trị nhỏ
Ví dụ sau sẽ dùng filter()
để tạo một mảng lọc không có các phần tử nào nhỏ hơn 10.
function isBigEnough(value) {
return value >= 10;
}
var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
// filtered is [12, 130, 44]
Lọc các giá trị không hợp lệ khỏi JSON
Ví dụ sau sẽ dùng hàm filter()
để lọc lại các phần tử của JSON chỉ chứa id
có giá trị số và khác 0.
var arr = [
{ id: 15 },
{ id: -1 },
{ id: 0 },
{ id: 3 },
{ id: 12.2 },
{ },
{ id: null },
{ id: NaN },
{ id: 'undefined' }
];
var invalidEntries = 0;
function isNumber(obj) {
return obj !== undefined && typeof(obj) === 'number' && !isNaN(obj);
}
function filterByID(item) {
if (isNumber(item.id) && item.id !== 0) {
return true;
}
invalidEntries++;
return false;
}
var arrByID = arr.filter(filterByID);
console.log('Filtered Array\n', arrByID);
// Filtered Array
// [{ id: 15 }, { id: -1 }, { id: 3 }, { id: 12.2 }]
console.log('Number of Invalid Entries = ', invalidEntries);
// Number of Invalid Entries = 5
Tìm kiếm trong mảng
Ví dụ sau dùng filter()
để lọc ra phần tử có nội dung thỏa chuỗi tìm kiếm
var fruits = ['apple', 'banana', 'grapes', 'mango', 'orange'];
/**
* Array filters items based on search criteria (query)
*/
function filterItems(query) {
return fruits.filter(function(el) {
return el.toLowerCase().indexOf(query.toLowerCase()) > -1;
})
}
console.log(filterItems('ap')); // ['apple', 'grapes']
console.log(filterItems('an')); // ['banana', 'mango', 'orange']
Ví dụ ở trên với ES2015
const fruits = ['apple', 'banana', 'grapes', 'mango', 'orange'];
/**
* Array filters items based on search criteria (query)
*/
const filterItems = (query) => {
return fruits.filter((el) =>
el.toLowerCase().indexOf(query.toLowerCase()) > -1
);
}
console.log(filterItems('ap')); // ['apple', 'grapes']
console.log(filterItems('an')); // ['banana', 'mango', 'orange']
Polyfill
filter()
chỉ được thêm vào đặc tả ECMA-262 phiên bản thứ 5; cho nên nó có thể không tồn tại trong một số hiện thực (implementation) của đặc tả. Bạn có thể xoay sở bằng cách thêm vào đoạn code bên dưới vào đầu script của bạn, cho phép sử dụng filter()
tại những nơi mà nó không được hỗ trợ sẵn. Giải thuật trong hàm polyfill này chính xác với đặc tả trong ECMA-262, 5th edition, với yêu cầu fn.call
trả về giá trị ban đầu của Function.prototype.bind()
, và Array.prototype.push()
không bị thay đổi.
if (!Array.prototype.filter){
Array.prototype.filter = function(func, thisArg) {
'use strict';
if ( ! ((typeof func === 'Function' || typeof func === 'function') && this) )
throw new TypeError();
var len = this.length >>> 0,
res = new Array(len), // preallocate array
t = this, c = 0, i = -1;
if (thisArg === undefined){
while (++i !== len){
// checks to see if the key was set
if (i in this){
if (func(t[i], i, t)){
res[c++] = t[i];
}
}
}
}
else{
while (++i !== len){
// checks to see if the key was set
if (i in this){
if (func.call(thisArg, t[i], i, t)){
res[c++] = t[i];
}
}
}
}
res.length = c; // shrink down array to proper size
return res;
};
}
Đặc tả
Đặc tả | Trạng thái | Ghi chú |
---|---|---|
ECMAScript 5.1 (ECMA-262) The definition of 'Array.prototype.filter' in that specification. |
Standard | Định nghĩa lần đầu. Được hiện thực trong JavaScript 1.6. |
ECMAScript 2015 (6th Edition, ECMA-262) The definition of 'Array.prototype.filter' in that specification. |
Standard | |
ECMAScript (ECMA-262) The definition of 'Array.prototype.filter' in that specification. |
Living Standard |
Tương thích trình duyệt
BCD tables only load in the browser