From 034f07389304adef516a375feebbf408f1399be6 Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Thu, 21 Oct 2021 11:31:04 +0300 Subject: Обновление Array.prototype.filter() (#2773) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Обновление Array.prototype.filter() * Apply suggestions from code review Co-authored-by: Sasha Sushko Co-authored-by: Sasha Sushko --- .../global_objects/array/filter/index.html | 300 --------------------- .../reference/global_objects/array/filter/index.md | 241 +++++++++++++++++ 2 files changed, 241 insertions(+), 300 deletions(-) delete mode 100644 files/ru/web/javascript/reference/global_objects/array/filter/index.html create mode 100644 files/ru/web/javascript/reference/global_objects/array/filter/index.md (limited to 'files/ru/web') diff --git a/files/ru/web/javascript/reference/global_objects/array/filter/index.html b/files/ru/web/javascript/reference/global_objects/array/filter/index.html deleted file mode 100644 index 2ed5099007..0000000000 --- a/files/ru/web/javascript/reference/global_objects/array/filter/index.html +++ /dev/null @@ -1,300 +0,0 @@ ---- -title: Array.prototype.filter() -slug: Web/JavaScript/Reference/Global_Objects/Array/filter -tags: - - Array - - ECMAScript5 - - JavaScript - - Method - - Prototype - - Reference - - filter - - polyfill -translation_of: Web/JavaScript/Reference/Global_Objects/Array/filter ---- -
{{JSRef}}
- -

Метод filter() создаёт новый массив со всеми элементами, прошедшими проверку, задаваемую в передаваемой функции.

- -
{{EmbedInteractiveExample("pages/js/array-filter.html")}}
- - - -

Синтаксис

- -
let newArray = arr.filter(callback(element[, index, [array]])[, thisArg])
-
- -

Параметры

- -
-
callback
-
Функция, которая будет вызвана для каждого элемента массива. Если функция возвращает true, то элемент остаётся в массиве, если false, то удаляется.
-
В функцию будет передано три аргумента:
-
-
-
element
-
Текущий обрабатываемый элемент в массиве.
-
index{{optional_inline}}
-
Индекс текущего обрабатываемого элемента в массиве.
-
array{{optional_inline}}
-
Массив, по которому осуществляется проход.
-
-
-
thisArg {{optional_inline}}
-
Значение, используемое в качестве this при вызове функции callback.
-
- -

Возвращаемое значение

- -

Вернётся новый массив с элементами, которые проходят тест, то есть callback вернёт true. Если ни один элемент не пройдёт тест, то будет возвращён пустой массив.

- -

Описание

- -

Метод filter() вызывает переданную функцию callback один раз для каждого элемента, присутствующего в массиве, и конструирует новый массив со всеми значениями, для которых функция callback вернула true или {{Glossary('Truthy', 'значение, становящееся true при приведении в boolean')}}. Функция callback вызывается только для индексов массива, имеющих присвоенные значения; она не вызывается для индексов, которые были удалены или которым значения никогда не присваивались. Элементы массива, не прошедшие проверку функцией callback, просто пропускаются и не включаются в новый массив.

- -

Функция callback вызывается с тремя аргументами:

- -
    -
  1. значение элемента;
  2. -
  3. индекс элемента;
  4. -
  5. массив, по которому осуществляется проход.
  6. -
- -

Если в метод filter() был передан параметр thisArg, при вызове callback он будет использоваться в качестве значения this. В противном случае, в качестве значения this будет использоваться значение {{jsxref("Global_Objects/undefined", "undefined")}}. В конечном итоге, значение this, наблюдаемое из функции callback, определяется согласно {{jsxref('Operators/this', 'обычным правилам определения this, видимого из функции')}}.

- -

Метод filter() не изменяет массив, для которого он был вызван.

- -

Диапазон элементов, обрабатываемых методом filter(), устанавливается до первого вызова функции callback. Элементы, добавленные в массив после начала выполнения метода filter(), не будут посещены функцией callback. Если существующие элементы массива изменятся, значения, переданные в функцию callback, будут значениями на тот момент времени, когда метод filter() посетит их; удалённые элементы посещены не будут.

- -

Примеры

- -

Отфильтровывание всех маленьких значений

- -

Следующий пример использует filter() для создания отфильтрованного массива, все элементы которого больше или равны 10, а все меньшие 10 удалены.

- -
function isBigEnough(value) {
-  return value >= 10;
-}
-
-let filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
-// массив filtered равен [12, 130, 44]
-
- -

Найти все простые числа в массиве

- -

Следующий пример возвращает все простые числа в массиве:

- -
let array = [4, 6, 8, 9, 12, 53, -17, 2, 5, 7, 31, 97, -1, 17];
-
-function isPrime(num) {
-    if (num <= 1)
-        return false;
-    else if (num === 2)
-        return true;
-    else {
-        for (let i = 2; i < num; i++)
-            if (num % i === 0)
-                return false;
-        return true;
-    }
-}
-
-console.log(array.filter(isPrime));   // [53, 2, 5, 7, 31, 97, 17]
- -

Фильтрация неверных записей в JSON

- -

В следующем примере метод filter() используется для создания отфильтрованного объекта JSON, все элементы которого содержат ненулевое числовое поле id.

- -
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('Отфильтрованный массив\n', arrByID);
-// Filtered Array
-// [{ id: 15 }, { id: -1 }, { id: 3 }, { id: 12.2 }]
-
-console.log('Количество ошибочных записей = ', invalidEntries);
-// Number of Invalid Entries = 5
-
-
- -

Поиск в массиве

- -

В следующем примере filter() используется для фильтрации содержимого массива на основе входных данных.

- -
var fruits = ['apple', 'banana', 'grapes', 'mango', 'orange'];
-
-/**
- * Элементы массива фильтруется на основе критериев поиска (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']
- -

ES2015 реализация

- -
const fruits = ['apple', 'banana', 'grapes', 'mango', 'orange'];
-
-/**
- * Элементы массива фильтруется на основе критериев поиска (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']
-
-
- -

Влияние на начальный массив (изменение, добавление и удаление)

- -

В следующих примерах проверяется поведение метода filter при изменении массива.

- -
// Изменение всех элементов
-let words = ['spray', 'limit', 'exuberant', 'destruction','elite', 'present']
-
-const modifiedWords = words.filter( (word, index, arr) => {
-  arr[index+1] +=' extra'
-  return word.length < 6
-})
-
-console.log(modifiedWords)
-// Обратите внимание, что есть три слова длиной менее 6, но так как они были изменены,
-// возвращается одно слово ['spray']
-
-// Добавление новых элементов
-words = ['spray', 'limit', 'exuberant', 'destruction','elite', 'present']
-const appendedWords = words.filter( (word, index, arr) => {
-  arr.push('new')
-  return word.length < 6
-})
-
-console.log(appendedWords)
-// Только три слова удовлетворяют условию, хотя `words` теперь имеет куда больше слов,
-// длинной меньше 6 символов: ['spray', 'limit', 'elite']
-
-// Удаление элементов
-words = ['spray', 'limit', 'exuberant', 'destruction', 'elite', 'present']
-const deleteWords = words.filter( (word, index, arr) => {
-  arr.pop()
-  return word.length < 6
-})
-
-console.log(deleteWords)
-// Заметьте, что 'elite' не получено, так как удалено из `words` до того,
-// как filter смог получить его: ['spray', 'limit']
- -

Полифил

- -

Метод filter() был добавлен к стандарту ECMA-262 в 5-м издании; поэтому он может отсутствовать в других реализациях стандарта. Вы можете работать с ним, добавив следующий код в начало ваших скриптов, он позволяет использовать filter() в реализациях, которые не поддерживают этот метод. Этот алгоритм является точно тем, что описан в ECMA-262 5-го издания; он предполагает, что fn.call вычисляется в оригинальное значение {{jsxref("Function.prototype.call()")}} и что {{jsxref("Array.prototype.push()")}} содержит своё оригинальное значение.

- -
if (!Array.prototype.filter) {
-  Array.prototype.filter = function(fun/*, thisArg*/) {
-    'use strict';
-
-    if (this === void 0 || this === null) {
-      throw new TypeError();
-    }
-
-    var t = Object(this);
-    var len = t.length >>> 0;
-    if (typeof fun !== 'function') {
-      throw new TypeError();
-    }
-
-    var res = [];
-    var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
-    for (var i = 0; i < len; i++) {
-      if (i in t) {
-        var val = t[i];
-
-        // ПРИМЕЧАНИЕ: Технически, здесь должен быть Object.defineProperty на
-        //             следующий индекс, поскольку push может зависеть от
-        //             свойств на Object.prototype и Array.prototype.
-        //             Но этот метод новый и коллизии должны быть редкими,
-        //             так что используем более совместимую альтернативу.
-        if (fun.call(thisArg, val, i, t)) {
-          res.push(val);
-        }
-      }
-    }
-
-    return res;
-  };
-}
-
- -

Спецификации

- - - - - - - - - - - - - - - - - - - - - - - - -
СпецификацияСтатусКомментарии
{{SpecName('ES5.1', '#sec-15.4.4.20', 'Array.prototype.filter')}}{{Spec2('ES5.1')}}Изначальное определение. Реализована в JavaScript 1.6.
{{SpecName('ES6', '#sec-array.prototype.filter', 'Array.prototype.filter')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-array.prototype.filter', 'Array.prototype.filter')}}{{Spec2('ESDraft')}}
- -

Совместимость с браузерами

- -
-

{{Compat("javascript.builtins.Array.filter")}}

-
- -

Смотрите также

- -
    -
  • {{jsxref("Array.prototype.forEach()")}}
  • -
  • {{jsxref("Array.prototype.every()")}}
  • -
  • {{jsxref("Array.prototype.some()")}}
  • -
  • {{jsxref("Array.prototype.reduce()")}}
  • -
diff --git a/files/ru/web/javascript/reference/global_objects/array/filter/index.md b/files/ru/web/javascript/reference/global_objects/array/filter/index.md new file mode 100644 index 0000000000..94bc6b25cf --- /dev/null +++ b/files/ru/web/javascript/reference/global_objects/array/filter/index.md @@ -0,0 +1,241 @@ +--- +title: Array.prototype.filter() +slug: Web/JavaScript/Reference/Global_Objects/Array/filter +tags: + - Array + - ECMAScript 5 + - JavaScript + - Method + - Prototype + - Reference + - Polyfill +translation_of: Web/JavaScript/Reference/Global_Objects/Array/filter +--- +{{JSRef}} + +Метод **`filter()`** **создаёт новый массив со всеми элементами**, прошедшими проверку, задаваемую в передаваемой функции. + +{{EmbedInteractiveExample("pages/js/array-filter.html")}} + +## Синтаксис + +```js +// Стрелочная функция +filter((element) => { ... } ) +filter((element, index) => { ... } ) +filter((element, index, array) => { ... } ) + +// Колбэк-функция +filter(callbackFn) +filter(callbackFn, thisArg) + +// Встроенная колбэк-функция +filter(function callbackFn(element) { ... }) +filter(function callbackFn(element, index) { ... }) +filter(function callbackFn(element, index, array){ ... }) +filter(function callbackFn(element, index, array) { ... }, thisArg) +``` + +### Параметры + +- `callbackFn` + + - : Функция-предикат, которая будет вызвана для проверки каждого элемента массива. Если функция возвращает `true`, то элемент остаётся в массиве, если `false`, то удаляется. + + Принимает три аргумента + + - `element` + - : Текущий обрабатываемый элемент в массиве. + - `index`{{optional_inline}} + - : Индекс текущего обрабатываемого элемента в массиве. + - `array`{{optional_inline}} + - : Обрабатываемый массив, на котором был вызван метод `filter()`. + +- `thisArg`{{optional_inline}} + - : Значение, используемое в качестве `this` при вызове колбэк-функции `callbackFn`. + +### Возвращаемое значение + +Вернётся новый массив с элементами, которые прошли проверку. Если ни один элемент не прошёл проверку, то будет возвращён пустой массив. + +## Описание + +Метод `filter()` вызывает переданную функцию `callback` один раз для каждого элемента, присутствующего в массиве, и создаёт новый массив со всеми значениями, для которых функция `callback` вернула [значение, которое может приведено к `true`](/ru/docs/Glossary/Truthy). Функция `callback` вызывается только для индексов массива с уже определёнными значениями; она не вызывается для индексов, которые были удалены или которым значения никогда не присваивались. Элементы массива, не прошедшие проверку функцией `callback`, просто пропускаются и не включаются в новый массив. + +Функция `callback` вызывается с тремя аргументами: + +1. значение элемента; +2. индекс элемента; +3. массив, по которому осуществляется проход. + +Если в метод `filter()` был передан параметр `thisArg`, при вызове `callback` он будет использоваться в качестве значения `this`. В противном случае в качестве значения `this` будет использоваться значение `undefined`. В конечном итоге, значение `this`, наблюдаемое из функции `callback`, определяется согласно [обычным правилам определения `this`](/en-US/docs/Web/JavaScript/Reference/Operators/this). + +Метод `filter()` не изменяет массив, для которого он был вызван. + +Элементы массива, обрабатываемые методом `filter()`, устанавливается до первого вызова функции `callback`. Элементы, добавленные в массив после начала выполнения метода `filter()`, либо изменённые в процессе выполнения, не будут обработаны функцией `callback`. Соответствующим образом, если существующие элементы удаляются из массива, они также не будут обработаны + +**Предупреждение:** одновременное изменение элементов, описанное в предыдущем параграфе, часто приводит к труднопонимаемому коду, поэтому не рекомендуется делать это (за исключением особых случаев). + +## Примеры + +### Фильтрация всех маленьких значений + +Следующий пример использует `filter()` для создания отфильтрованного массива, все элементы которого больше или равны 10, а все меньшие 10 удалены. + +```js +function isBigEnough(value) { + return value >= 10; +} + +let filtered = [12, 5, 8, 130, 44].filter(isBigEnough); +// массив filtered теперь содержит [12, 130, 44] +``` + +### Найти все простые числа в массиве + +Следующий пример возвращает все простые числа в массиве: + +```js +const array = [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; + +function isPrime(num) { + for (let i = 2; num > i; i++) { + if (num % i == 0) { + return false; + } + } + return num > 1; +} + +console.log(array.filter(isPrime)); // [2, 3, 5, 7, 11, 13] +``` + +### Фильтрация неверных записей в JSON + +В следующем примере метод `filter()` используется для создания отфильтрованного JSON-объекта, все элементы которого содержат ненулевое числовое поле `id`. + +```js +let arr = [ + { id: 15 }, + { id: -1 }, + { id: 0 }, + { id: 3 }, + { id: 12.2 }, + { }, + { id: null }, + { id: NaN }, + { id: 'undefined' } +] + +let invalidEntries = 0 + +function filterByID(item) { + if (Number.isFinite(item.id) && item.id !== 0) { + return true + } + invalidEntries++ + return false; +} + +let arrByID = arr.filter(filterByID) + +console.log('Отфильтрованный массив\n', arrByID) +// Отфильтрованный массив +// [{ id: 15 }, { id: -1 }, { id: 3 }, { id: 12.2 }] + +console.log('Количество некорректных элементов = ', invalidEntries) +// Количество некорректных элементов = 5 +``` + +### Поиск в массиве + +В следующем примере `filter()` используется для фильтрации содержимого массива на основе входных данных. + +```js +var fruits = ['apple', 'banana', 'grapes', 'mango', 'orange']; + +/** + * Элементы массива фильтруется на основе критериев поиска (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'] +``` + +#### Реализация с использованием ES2015 + +```js +const fruits = ['apple', 'banana', 'grapes', 'mango', 'orange']; + +/** + * Элементы массива фильтруется на основе критериев поиска (query) + */ +const filterItems = (arr, query) => { + return arr.filter(el => el.toLowerCase().indexOf(query.toLowerCase()) !== -1) +} + +console.log(filterItems('ap')); // ['apple', 'grapes'] +console.log(filterItems('an')); // ['banana', 'mango', 'orange'] +``` + +### Модификация изначального массива (изменение, добавление и удаление) + +В следующих примерах проверяется поведение метода `filter` при изменении массива. + +```js +// Изменение всех элементов +let words = ['spray', 'limit', 'exuberant', 'destruction','elite', 'present'] + +const modifiedWords = words.filter( (word, index, arr) => { + arr[index+1] +=' extra' + return word.length < 6 +}) + +console.log(modifiedWords) +// Обратите внимание, что есть три слова длиной менее 6, но так как они были изменены, +// возвращается одно слово ['spray'] + +// Добавление новых элементов +words = ['spray', 'limit', 'exuberant', 'destruction','elite', 'present'] +const appendedWords = words.filter( (word, index, arr) => { + arr.push('new') + return word.length < 6 +}) + +console.log(appendedWords) +// Только три слова удовлетворяют условию, хотя `words` теперь имеет куда больше слов, +// длинной меньше 6 символов: ['spray', 'limit', 'elite'] + +// Удаление элементов +words = ['spray', 'limit', 'exuberant', 'destruction', 'elite', 'present'] +const deleteWords = words.filter( (word, index, arr) => { + arr.pop() + return word.length < 6 +}) + +console.log(deleteWords) +// Заметьте, что 'elite' не получено, так как удалено из `words` до того, +// как filter смог получить его: ['spray', 'limit'] +``` + +## Спецификации + +{{Specifications}} + +## Поддержка браузерами + +{{Compat}} + +## Смотрите также + +- Полифил `Array.prototype.filter` в библиотеке [`core-js`](https://github.com/zloirock/core-js#ecmascript-array) +- {{jsxref("Array.prototype.forEach()")}} +- {{jsxref("Array.prototype.every()")}} +- {{jsxref("Array.prototype.some()")}} +- {{jsxref("Array.prototype.reduce()")}} +- {{jsxref("Array.prototype.find()")}} -- cgit v1.2.3-54-g00ecf