#javascript
#javascript
Вопрос:
В программе, которую я пишу, у меня есть многомерный массив, и мне нужно выполнить некоторую операцию только над самыми внутренними объектами.
Есть ли лучший способ написать этот код?
for (const threeDimensionalArray of fourDimensionalArray) {
for (const twoDimensionalArray of threeDimensionalArray) {
for (const oneDimensionalArray of twoDimensionalArray) {
for (const obj of oneDimensionalArray) {
// do something
}
}
}
}
Что-то вроде:
for (const obj someSpecialKeyword fourDimensionalArray) {
// do something
}
Примечание: я знаю одно решение, которое использует функцию выравнивания. Проблема с использованием функции выравнивания заключается в том, что эта итерация будет часто использоваться в программе, поэтому я беспокоюсь о производительности. Даже если я сохраню этот многомерный массив в двух форматах (плоский и многомерный), это может вызвать проблемы с производительностью, потому что этот массив также сильно изменен, а также удлиняет код.
Каков был бы наилучший подход здесь?
Комментарии:
1. Какова фактическая структура (т. Е. Формальный тип данных) массива? Я предполагаю, что это неровный массив (поскольку JavaScript не поддерживает истинные многомерные массивы).
2. Рассматривали ли вы возможность написания функции итератора?
3. Самый внутренний тип — это объект с атрибутами
4.
flatMap
Функция — это то, что я бы использовал, а затем перебирал все элементы, если производительность является ключевой… вы уверены, что хотите решить эту проблему с помощью JavaScript?
Ответ №1:
Я знаю одно решение, которое использует функцию выравнивания
Я предполагаю, что под «функцией выравнивания» вы подразумеваете функцию редуктора? (К сожалению, Array.prototype
функции JavaScript, такие как reduce
, map
, filter
и т. Д., Выполняют полные копии на каждом шаге).
Альтернативой является написание функции генератора (она же функция итератора):
function* getAll( fourDimensionalArray ) { // The asterisk is not a typo.
for (const threeDimensionalArray of fourDimensionalArray) {
for (const twoDimensionalArray of threeDimensionalArray) {
for (const oneDimensionalArray of twoDimensionalArray) {
for (const obj of oneDimensionalArray) {
yield obj;
}
}
}
}
}
Используется так:
for( const item of getAll( fourDimensionalArray ) ) {
// do something
}
Функции генератора очень эффективны и не вызывают операцию копирования массива.
Комментарии:
1. благодаря вам я сегодня узнал кое-что новое; мой голос
Ответ №2:
Вы могли бы использовать рекурсивную функцию, которая принимает массив или элемент и обратный вызов для не массивов.
Эта функция не зависит от фиксированной структуры.
function iter(value, cb) {
if (Array.isArray(value)) {
for (const item of value) iter(item, cb);
} else {
cb(value);
}
}
Комментарии:
1. Рассмотрим
const arr = []; arr.push( arr ); iter( arr, console.log );
2. «у этого массива нет этажа» — я не знаком с термином «этаж» в контексте массивов — можете ли вы объяснить? Я хотел сказать, что ваша функция уязвима для переполнения стека при работе с циклическим объектом-графом.
3. с технической точки зрения массив имеет циклическую ссылку и не может получить конечный элемент массива.