Задача по функциям, псевдомассиву arguments и оператору расширения [как из произвольно вложенных массивов сделать один плоский?]

Изучаю тему функций. Столкнулся с интересной задачей

// Сделайте полное объединение аргументов с раскрытием массивов всех уровней

function concat3() {

}

результат работы функции следующий:
console.log(concat3(1, ‘a’, [3, 4], [[5]], [[6]], [[[7]]] ));
// => [1, “a”, 3, 4, 5, 6, 7]
console.log(concat3([1]));
// => [1]

Так и не смог придумать рекурсивный обход для такой задачи. Какие будут мысли?
Кто сталкивался? Какие есть варианты решения с циклом/без?

function isArr(el) {
	return Array.isArray(el)
}

function concat3() {
	let res = []
	for (let i = 0; i < arguments.length; i += 1) {
		if (isArr(arguments[i])) {
			res = res.concat(concat3.apply(null, arguments[i]))
		} else {
			res.push(arguments[i])
		}
	}
	return res
}

Вот этот момент “хитрый”. Он моделирует сиуацию вида “если аргумент args[i] - массив, то вызови concat3 с элементами этого массива как аргментами. Получишь в итоге массив и его сконкатенируй с масивом результатов.”.

if (isArr(args[i])) {
			res = res.concat(concat3.apply(null, args[i]))

Есть еще условно брутальный подход. Он “играет” с тем как себя ведет метод concat, и будет корректно работать только для js (или других языков с таким-же набором функционала методов).

function concat3() {
	let res = [...arguments]
	while (res.some(Array.isArray)) {
		res = Array.prototype.concat.apply([], res)
	}
	return res
}

Подобного рода задача есть и на jscourse.com. Там же есть тесты на которых можно обкатать свое решение https://a.jscourse.com/ru/challenge/flatten

1 лайк

Спасибо! Вникаю

первую реализацию в принципе понял. Что-то типа такого и пытался сделать. Единственное не совсем ясна специфика вызова через apply c null указателем. Я просто пушил результат рекурсивного вызова, но все время ловил стэк оверфлоу. Что можно читануть по теме?
Или это в разделах дальше (там же еще я так понимаю дальше функции разбираются)

вторую реализацию не понял вообще. Но это наверное пока для меня сложная материя )))
вернусь к ней попозже. После чтива блога Soshnikov пока прихожу в себя :)

concat3.apply(null, arguments[i]) это типа "вызови функцию concat3 со значением параметров как в массиве arguments[i]".

null - это значение this при вызове метода apply.

Ниже изолированный пример.

function ppp(a, b, c) {
	console.log(this, a, b, c)
}

var args = [10, 20, 30]
ppp.apply(null, args) // null, 10, 20, 30
1 лайк

Того же эффекта вызоыва функции с аргументами из массива можно добиться спред оператором.

1 лайк

спасибо!