„Последната ми публикация“ обхваща рекурсивно Array.map
. Въпреки че е добър ресурс за обучение, „не препоръчвам“ никой да го използва в своите приложения.
Същото важи и за внедряването на Array.filter
рекурсивно.
Вместо тази (опростена) традиционна версия:
filter = (predicate, arr) => { const filteredArray = []; for (let i = 0; i < arr.length; i++) { let currentItem = arr[i]; if (predicate(currentItem)) { filteredArray.push(currentItem); } } return filteredArray; };
Помислете за това:
filter = (pred, [head, ...tail]) => head === undefined ? [] : ( pred(head) ? [head, ...filter(pred, tail)] : [...filter(pred, tail)] );
Ако разбирате рекурсивния масив.map
, това е лесно 💲.
Все още улавяме първия елемент на масива в променлива, наречена head
, а останалите в отделен масив, наречен tail
.
И със същия основен случай – ако head
е undefined
, върнете празен масив и завършете итерацията.
Но имаме друго условно изявление: поставете head
в новия масив само ако pred(head)
е true
, защото filter
работи, като тества всеки елемент спрямо предикатна функция. Само когато предикатът върне true
, добавяме този елемент към новия масив.
Ако pred(head)
не върне true
, просто извикайте filter(pred, tail)
без head
.
Нека бързо да разширим и преминем през това в конзолата на Chrome.
filter = (pred, [head, ...tail]) => { if (head === undefined) return []; if (pred(head)) { debugger; return [head, ...filter(pred, tail)]; } debugger; return [...filter(pred, tail)]; };
И потърсете числа ≤ 10:
filter(x => x <= 10, [1, 10, 20]);
Тъй като [1, 10, 20]
на нашия масив, head
е първият елемент, 1, а tail
е масив от останалите: [10, 20]
.
Предикатът проверява дали x
≤ 10, така че pred(1)
връща true
. Ето защо спряхме на debugger
израза на ред 4.
Тъй като текущият head
премина теста, му е разрешено влизане в нашия филтриран масив. Но не сме готови, така че извикваме filter
отново със същия предикат и сега tail
.
Преминете към следващия debugger
.
Извикахме filter
с [10, 20]
, така че head
сега е 10, а tail
е [20]
. И така, как tail
става по-малък с всяка следваща итерация?
Отново сме на debugger
на ред 4, защото защото 10 ≤ 10. Преминете към следващата точка на прекъсване.
head
вече е 20, а tail
е празен.
Тъй като 20 › 10, pred(head)
връща false
и нашият филтриран масив няма да го включва. Ще се обадим на filter
още веднъж без head
.
Този следващ път обаче filter
ще се спаси на ред 2. Деструктурирането на празен масив ви дава undefined
променливи. Продължете след тази точка на прекъсване, за да получите върнатата стойност.
Това ми изглежда правилно!
Помислете за коментиране, ако това е помогнало. Рекурсивният reduce
вероятно е следващият. 😁
Продължете да кодирате. До следващия път!
Пази се,
Yazeed Bzadough