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?
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]));
undefined for the stop condition, what if your input array is [1, undefined, 3]?undefined values.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;
}
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;}
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([]));
undefined for the stop condition, what if your input array is [1, undefined, 3]?
[] == []isfalse, so you will have to check iflist.length == 0for the stop condition.