4.2. Демонстрация - Уменьшение вложенности массива
Шаг 1
Посмотрим на следующую довольно прикладную задачу. У нас есть массив с элементами и другими массивами — вложенность может быть любой. Нужно устранить вложенность, сохранив очерёдность элементов. Легче всего понять эту задачу, просто посмотрев на примеры. Попробуйте самостоятельно решить эту задачу с помощью рекурсии! P. S. Сейчас эту задачу решает встроенный Array.prototype.flat, но раньше его не было.
import {test} from "./tester";
/*
Примеры:
flat([]) // []
flat([[1, 5], 5, 10]) // [1, 5, 5, 10]
flat([1, 2, [3, 4]]) // [1, 2, 3, 4]
flat([1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]]) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
*/
function flat(array) {
return [];
}
test(flat([]), []);
test(flat([[1, 5], 5, 10]), [1, 5, 5, 10]);
test(flat([1, 2, [3, 4]]), [1, 2, 3, 4]);
test(flat([1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]]), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
Шаг 2
Начнём с простого: предположим, что у нас все элементы — это не массивы. Тогда каждый случай будет для нас базовым, просто итеративно переложим один массив в другой.
import {test} from "./tester";
/*
Примеры:
flat([]) // []
flat([[1, 5], 5, 10]) // [1, 5, 5, 10]
flat([1, 2, [3, 4]]) // [1, 2, 3, 4]
flat([1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]]) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
*/
function flat(array) {
const result = [];
for (const element of array) {
result.push(element);
}
return result;
}
test(flat([]), []);
test(flat([[1, 5], 5, 10]), [1, 5, 5, 10]);
test(flat([1, 2, [3, 4]]), [1, 2, 3, 4]);
test(flat([1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]]), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
Шаг 3
А теперь введём рекурсивный случай. Если встречаем массив, то будем вызывать flat уже на нём. Этот случай будет приближать нас к базовому — рано или поздно вложенность закончится, и мы встретим «простые» элементы.
import {test} from "./tester";
/*
Примеры:
flat([]) // []
flat([[1, 5], 5, 10]) // [1, 5, 5, 10]
flat([1, 2, [3, 4]]) // [1, 2, 3, 4]
flat([1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]]) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
*/
function flat(array) {
const result = [];
for (const element of array) {
if (Array.isArray(element)) {
result.push(...flat(element))
} else {
result.push(element);
}
}
return result;
}
test(flat([]), []);
test(flat([[1, 5], 5, 10]), [1, 5, 5, 10]);
test(flat([1, 2, [3, 4]]), [1, 2, 3, 4]);
test(flat([1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]]), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
File tester.js
const results = document.getElementById('results')
export function test(rawLeft, rawRight) {
const result = document.createElement('li');
// Небольшой хак для сравнения массивов. Не делайте так в production!
const left = JSON.stringify(rawLeft);
const right = JSON.stringify(rawRight);
if (left === right) {
result.innerHTML = "Тест пройден!";
result.style.color = "green";
} else {
result.innerHTML = `Тест не пройден! ${left} не равно ${right}`;
result.style.color = "red";
}
results.appendChild(result);
}