I have an example of nested array:
var testArray = [1,2,[3,4,[5,6],7],8,9,[10,11],12];
Here is my function for getting nested array length:
Array.prototype.getLength = function() {
var sum = 0;
function getMultiLength(array) {
for (count = 0; count < array.length; count ++) {
sum ++;
if (!array[count].length) {
getMultiLength(array[count]);
}
}
}
getMultiLength(this.valueOf());
return sum;
};
My expectation for result would be 12, but instead what I got is infinite loop:
testArray.getLength(); //infinite loop
Anyone know why and how to get nested array length?
I have an example of nested array:
var testArray = [1,2,[3,4,[5,6],7],8,9,[10,11],12];
Here is my function for getting nested array length:
Array.prototype.getLength = function() {
var sum = 0;
function getMultiLength(array) {
for (count = 0; count < array.length; count ++) {
sum ++;
if (!array[count].length) {
getMultiLength(array[count]);
}
}
}
getMultiLength(this.valueOf());
return sum;
};
My expectation for result would be 12, but instead what I got is infinite loop:
testArray.getLength(); //infinite loop
Anyone know why and how to get nested array length?
Share Improve this question edited Oct 6, 2016 at 15:48 Trung0246 asked Oct 6, 2016 at 4:12 Trung0246Trung0246 6891 gold badge11 silver badges21 bronze badges 09 Answers
Reset to default 11Problem with your code
Your existing code fails because the check for recursing is backward. You want to recurse if the length is non-zero. So it should be
if (array[count].length) getMultiLength(array[count]);
else sum++;
As your code stands, getMultiLength
will be called even if array[count]
is not an array (because if array[count]
is not an array, length
will be undefined). So it will keep recursing forever. This would be pretty easy to figure out by just stepping through your code in the debugger.
By the way, you don't need this.valueOf()
. That is the same as this
in this case.
Tweaking your code
But actually, you could streamline your code by eliminating the unnecessary inner function, and using the return value of the recursive calls:
Array.prototype.getLength = function() {
let sum = 0;
for (let count = 0; count < this.length; count ++) {
sum += this[count].length ? this[count].getLength() : 1;
}
return sum;
};
Some people might prefer to write this using reduce
:
Array.prototype.getLength = function() {
return this.reduce((sum, elt) =>
sum + (elt.length ? elt.getLength() : 1), 0);
};
Another solution using flattening
An alternative solution is to flatten the array, then find the length of the flattened array. Here we use a generator to create a flattener which is real easy to read and understand (ES6 feature):
function *flatten(array) {
for (elt of array)
if (Array.isArray(elt)) yield *flatten(elt);
else yield elt;
}
var testArray = [1,2,[3,4,[5,6],7],8,9,[10,11],12];
console.log(Array.from(flatten(testArray)).length);
Alternative implementation of flatten
Or, use your own favorite implementation of flatten
, such as this recursive version:
function flatten(value) {
return Array.isArray(value) ? [].concat(...value.map(flatten)) ? value;
}
or in ES5
function flatten(value) {
return Object.prototype.toString.call(value) === '[object Array]' ?
[].concat.apply([], value.map(flatten)) :
value;
}
Putting it on the Array
prototype
If you insist on putting this on the prototype, then
Object.defineProperty(Array.prototype, 'getLength', {
value() { return flatten(this).length; }
});
Use defineProperty
to make this property non-enumerable, non-configurable etc.
All the answers above are helpful, just adding another simple answer. Hope it's useful to someone in the future.
const getLength = arr => arr.flat(Infinity).length;
var testArray = [1,2,[3,4,[5,6],7],8,9,[10,11],12];
console.log(getLength(testArray));
We are using the flat()
method here to flatten the array into a single array and then calculate the length of it. Note that we have passed the depth as Infinity
because we want to go all the way deep and count the entire length.
The flat() method creates a new array with all sub-array elements concatenated into it recursively up to the specified depth. In our case we will define the depth as Infinity
Read more on flat()
Try this :
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
var testArray = [1,2,[3,4,[5,6],7],8,9,[10,11],12];
var s = 1;
$.each(testArray, function(index, value){
s = s + $(this).length;
});
console.log(s);
There is a recursion call for nested arrays to count their non-array items:
var testArray = [1, 2, [3, 4, [5, 6], 7], 8, 9, [10, 11], 12];
Array.prototype.getLength = function () {
function getMultiLength(array) {
var sum = 0;
for (var count = 0; count < array.length; count++) {
if (Array.isArray(array[count])) {
sum += getMultiLength(array[count]);
} else {
sum++;
}
}
return sum;
}
return getMultiLength(this.valueOf());
};
alert(testArray.getLength());
I used recursive call to find nested array length
var testArray = [1,2,[3,4,[5,6],7],8,9,[10,11],12];
var totalLen=0;
function length(arr){
for(var ele in arr){
if(Array.isArray(arr[ele])){
length(arr[ele])
}else{
totalLen++;
}
}
}
length(testArray);
console.log(totalLen); //o/p 12
Improvised not using global variable here
var testArray = [1,2,[3,4,[5,6],7],8,9,[10,11],12];
var ArrayUtils=function(){
var totalLength=0;
function getNestedArrayLength(arr){
for(var ele in arr){
if(Array.isArray(arr[ele])){
getNestedArrayLength(arr[ele])
}else{
totalLength++;
}
}
}
function getLength(arr){
getNestedArrayLength(arr);
return totalLength;
}
return {
getLength:getLength
}
}
var aU=new ArrayUtils();
var length=aU.getLength(testArray);
console.log(length); //Op 12
Two methods that i would like to contribute with;
Recursive:
var testArray = [1,2,[3,4,[5,6],7],8,9,[10,11],12];
flat = a => a.reduce((p,c) => p.concat(Array.isArray(c) ? flat(c) : c),[]);
result = flat(testArray).length;
console.log(result);
Guerilla:
var testArray = [1,2,[3,4,[5,6],7],8,9,[10,11],12];
result = JSON.stringify(testArray).match(/,/g).length+1;
console.log(result);
[].concat.apply([[]], testArray).length
for info on apply see:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
Hello here is the answer using Array.isArray to indentify if it is array or not, then recalling the function to do that one more time and so so on.
let test = [1, [2, [3, [4, [5, 6],7,[8,9,10,[11,12]]]]]];
let length = 0;
function len(array){
for(let i in array){
if(Array.isArray(array[i])){
len(array[i])
}else{
length++
}
}
return length;
};
len(test)
console.log(length)
Try this:
Array.prototype.getLength = function() {
var sum = 0;
function getMultiLength(array) {
for (var count = 0; count < array.length; count ++) {
sum ++;
if (array[count].length) {
getMultiLength(array[count]);
}
}
}
getMultiLength(this.valueOf());
return sum;
};
var testArray = [1,2,[3,4,[5,6],7],8,9,[10,11],12];
testArray.getLength()
- Do not use GLOBAL variable count.
- Why do you want to count array if it is empty?