2016-06-11 2 views
0

В следующем коде matrix.length учитывает только первый массив, а не второй. Как я могу подсчитать многомерный массив, чтобы результат для следующего кода составлял 10?Как определить длину многомерного массива в javascript?

var matrix = [1,2,3,4,5,6, [1,2,3,4]]; 

console.log(matrix.length - 1) 
+0

Что такое ожидаемое значение, которое вы ищите? – Mikey

+0

Вы хотите 10 в результате? – vaso123

+2

Непонятно, что вы просите. Пожалуйста, включите ожидаемый результат в описанный случай, а также опишите проблему в целом (этот случай довольно специфичен). – hon2a

ответ

11

Нет ярлыка, вы должны суммировать длины массивов. Если у вас есть только два измерения, то:

var matrix = [1,2,3,4,5,6, [1,2,3,4]]; 
 
var sum = matrix.reduce(function(acc, entry) { 
 
    return acc + (Array.isArray(entry) ? entry.length : 1); 
 
}, 0); 
 
console.log(sum);

Если вы можете иметь больше размеров, вам нужна рекурсия. Как косоглазие отметил в комментарии, что делает выше рекурсивной только вопрос предоставления нашего reduce обратного вызова имя, а затем делать reduce снова вместо того, чтобы просто используя array.length:

var matrix = [1,2,3,4,5,6, [1,2,[3,4]]]; 
 
var sum = matrix.reduce(function callback(acc, entry) { 
 
    return acc + (Array.isArray(entry) ? entry.reduce(callback, 0) : 1); 
 
}, 0); 
 
console.log(sum);


Некоторые примечания:

  • Array.isArray и Array#reduce были добавлен в ES5 (в 2009 году) и поэтому должен быть доступен практически в любом современном браузере (так, а не в IE8); они могут быть зачищены/полифорированы в старых браузерах.
  • На самом деле JavaScript не имеет многомерных массивов. Он имеет массивы массивов.
  • В приведенном выше примере рекурсии используется конструкция, называемая с именем function function для callback. У NFE есть плохое имя, потому что много лет назад браузеры ошиблись несколькими разными способами, но в эти дни все в порядке. (Если вы использовали выше на IE8   — включая polyfills для вещей это отсутствующими   — даже он бы работать, даже если IE8 gets NFEs wrong.)
+2

Всего несколько дополнительных символов, чтобы сделать его рекурсивным ... 'entry.length' становится' entry.reduce (fn, 0) '* (и' fn' для имени обратного вызова) *. Мог бы тоже изо всех сил! –

+1

@NinaScholz: Где моя голова? :-) Благодаря. –

+1

@squint: Хороший! Готово. –

1

Опираясь на @ T.J. Решение Crowder с reduce, я бы предложил немного изменить ситуацию, поэтому в коде есть только одно упоминание о reduce. А чтобы оживить его, это с синтаксисом стрелки:

function entries(a) { 
 
    return Array.isArray(a) ? a.reduce((acc, el) => acc + entries(el), 0) : 1; 
 
} 
 

 
var matrix = [1,2,3,4,5,6, [1,2, [3,4]]]; 
 

 
console.log(entries(matrix));

Таким образом, он будет работать даже аргументы не-массив: возвращаемое значение равно 1 в этом случае. Очевидно, это не так важно.

Смежные вопросы