1

I'm trying to write a recursive function to count the number of items in a array using Javascript.

I can do it in Python:

def count(list):
 if list == []:
  return 0
 return 1 + count(list[1:]) 

How can I do it in ES5 and ES6?

3
  • Is it a two dimensional array? If it isn’t, you could use length(). Commented May 9, 2019 at 4:32
  • Why you need this when you have the .length property? Note also, that on Javascript [] == [] is false, so you will have to check if list.length == 0 for the stop condition. Commented May 9, 2019 at 4:48
  • 1
    The title of the question is a little confusing I would suggest you edit it as "Javascript: Recursively count the number of elements in array?" Because that's what you want to do according to the body and code sample. Commented May 9, 2019 at 11:17

5 Answers 5

2

The most es6-ish, fp-ish way of writing it. Works on all iterables.

const count = xs =>
  xs[Symbol.iterator]().next().done
    ? 0
    : 1 + (([,...xr]) => count(xr))(xs);

console.log(count([1,2,3]));
console.log(count("hello123"));
console.log(count({
    *[Symbol.iterator]() {
        yield 1;
        yield 2;
        yield 3;
        yield 4;
    }
}));
console.log(count([]));
console.log(count([1, undefined, 2]));

Sign up to request clarification or add additional context in comments.

3 Comments

Just a note, about comparing with undefined for the stop condition, what if your input array is [1, undefined, 3]?
@Shidersz yeah that's a bug, thanks for pointing it out. I'll update the answer.
Yeah, I was thinking about this as the first option too. After all, this case should not be a problem if the input data can warranty not to have undefined values.
1

Counting elements is ridicoulous since you can just take the length property. It will be O(1) and do what you expect. As for summing or doing something with the elements:

// recursively. Works only on arrays 
const sumElements = (arr) => {
  if (arr.length === 1) return arr[0];

  const [e, ...rest] = arr;
  return e + sumElements(rest);
}


// recursively and effiecent. Works only on arrays
const sumElements = (arr) => {
  const helper = (index, acc) => index < 0 ? acc helper(index - 1, acc + arr[index]);
  return helper(arr.length-1, 0);
}


// using higher order functions. Works for all collections that has reduce defined
const sumElements = list => list.reduce((acc, e) => acc + e), 0);

// using iterators. Works for all collections that has iterator defined
const sumElements = (list) => {
  let sum = 0;
  for (const e of list) {
    sum += e;
  }
  return sum;
}

Comments

1

First, you have to know that arrays have a .length property for this purpose. Knowing this, and if you still wants to get it by recursion, I will do something like next, that uses the iterator and Array.slice(). This approach avoid use of .length property to detect the stop condition.

const count = (list) =>
{
    let ite = list[Symbol.iterator]();

    if (ite.next().done)
        return 0;
    else
        return 1 + count(list.slice(1));
}

console.log(count([]));
console.log(count([undefined, null]));
console.log(count([1, 2, undefined, 3, 4]));
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

Comments

1

ES6 recursive function:

const count = arr => arr[0] == undefined ? 0 : 1 + count(arr.slice(1));
console.log(count([1, 2, 3]));
console.log(count([]));

ES5:

function count(arr) {
  return arr[0] == undefined ? 0 : 1 + count(arr.slice(1));
}
console.log(count([1, 2, 3]));
console.log(count([]));

1 Comment

Just a note, about comparing with undefined for the stop condition, what if your input array is [1, undefined, 3]?
1

Here's two solutions.

const count1 = ([x, ...xs]) => x ? 1 + count1(xs) : 0
const count2 = (xs) => xs.reduce((y) => y + 1, 0)

console.log(count1([1, 2, 3, 4, 5]))
console.log(count2([1, 2, 3, 4, 5]))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.