Poznajemy odmianę wzorca arr-handler-loop. Wzorzec arr-handler-loop-deeperOrPush pokaże nam, jak możemy rozpłaszczyć tablicę. Do dzieła.
Najpierw wzorzec z poprzedniej lekcji:
function getTextNodes(el){
var textNodes = []
function handler(node){
if(node === null)
return;
if(node.nodeType === Node.TEXT_NODE)
textNodes.push(node);
if(node.nodeType !== Node.TEXT_NODE){
node.childNodes.forEach((childNode) => {
handler(childNode);
});
}
}
handler(el);
return textNodes;
}
Rozumiemy ogólną logikę. Teraz piszemy funkcję robiącą Arr.flat:
const flatten = (nestedArr) => {
const flatArr = [];
const _flatten = (arr) => {
let counter = 0
while (counter < arr.length) {
const val = arr[counter];
if (Array.isArray(val))
_flatten(val);
else
flatArr.push(val);
counter++;
}
}
_flatten(nestedArr);
return flatArr;
}
let arr = [1,2,[3],[4,5],6,[7,[8,[9,10]]]];
console.log(flatten(arr));
//Array(10) [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
Zasada prosta:
- Tablica, handler, handler, tablica
- Handler bierze tablicę i bez ceregieli zaczyna iterację po niej
- Jeżeli element tablicy jest tablicą to to zostaje przekazany rekurencyjnie do handlera
- Jeżeli jest zwykłym elementem, zostaje dopisany do tej wyjściowej
- Handler wywołany na pierwotnie przekazanej tablicy i wynik zwrócony
- Wszystko działa dzięki closures.
- Zwróćmy uwagę, że np. w PHP nasza funkcja handler musiałaby mieć „use ($flatArr)” żeby mieć dostęp do tej tablicy poziom wyżej. W różnych językach jest różnie.