Количество «определенных» элементов массива - PullRequest
32 голосов
/ 28 марта 2012

Учитывая следующий массив:

var arr = [undefined, undefined, 2, 5, undefined, undefined];

Я хотел бы получить количество элементов, которые определены (т.е. те, которые не undefined). Есть ли хороший способ сделать это, кроме циклического перебора массива?

Ответы [ 7 ]

57 голосов
/ 28 марта 2012

В последних версиях браузера вы можете использовать фильтр

var size = arr.filter(function(value) { return value !== undefined }).length;

console.log(size);

Другой способ, если браузер поддерживает indexOf для массивов:

var size = arr.slice(0).sort().indexOf(undefined);

Если для абсурда в массиве есть элементы, состоящие только из одной цифры, вы можете использовать этот подвох:

console.log(arr.join("").length);

Есть несколько методов, которые вы можете использовать, но в конце мы должны увидеть, действительно ли это стоит делать вместо цикла.

10 голосов
/ 28 марта 2012

Массив length - это не количество элементов в массиве, это наибольшее значение index + 1.Свойство length сообщит правильное количество элементов, только если в последовательных индексах есть допустимые элементы.

var a = [];
a[23] = 'foo';
a.length;  // 24

Сказав это, невозможно исключить неопределенные элементы из числа без использования какой-либо формы цикла.

2 голосов
/ 28 марта 2012

Нет, единственный способ узнать, сколько элементов не является неопределенными, - это просмотреть их и подсчитать. Это не означает, что вы должны писать цикл, хотя, просто что-то, где-то должно это делать. (См. № 3 ниже, почему я добавил это предупреждение.)

Как вы проходите и считаете их, зависит от вас. Есть много способов:

  1. Стандартная for петля от 0 до arr.length - 1 (включительно).
  2. A for..in loop при условии, что вы принимаете правильные меры предосторожности .
  3. Любая из нескольких новых функций массива из ECMAScript5 (при условии, что вы используете движок JavaScript, который их поддерживает, или вы включили шайбу ES5, так как они все шим-совместимы), например some, filter или reduce, передавая соответствующую функцию. Это удобно не только потому, что вам не нужно явно писать цикл, но и потому, что использование этих функций дает движку JavaScript возможность оптимизировать цикл, который он выполняет внутри, различными способами. (На самом ли деле делает , зависит от двигателя.)

... но все это равнозначно зацикливанию, явно или (в случае новых возможностей массива) неявно.

0 голосов
/ 21 ноября 2017

Удалите значения, затем отметьте (при желании снимите отметку с нуля)

const x = A.filter(item => item !== undefined || item !== null).length

С Lodash

const x = _.size(_.filter(A, item => !_.isNil(item)))
0 голосов
/ 10 июня 2015

Если значения undefined неявны, вы можете сделать следующее:

var len = 0;
for (var i in arr) { len++ };

значения undefined неявны, если вы не установите их явно

//both are a[0] and a[3] are explicit undefined
var arr = [undefined, 1, 2, undefined];

arr[6] = 3;
//now arr[4] and arr[5] are implicit undefined

delete arr[1]
//now arr[1] is implicit undefined

arr[2] = undefined
//now arr[2] is explicit undefined
0 голосов
/ 28 марта 2012

Цикл и счет во всех браузерах:

var cnt = 0;
for (var i = 0; i < arr.length; i++) {
    if (arr[i] !== undefined) {
        ++cnt;
    }
}

В современных браузерах:

var cnt = 0;
arr.foreach(function(val) {
    if (val !== undefined) { ++cnt; }
})
0 голосов
/ 28 марта 2012

К сожалению, нет. Вам придется пройти через цикл и сосчитать их.

РЕДАКТИРОВАТЬ:

var arrLength = arr.filter(Number);
alert(arrLength);

...