# Counting predicates

## How to find the first item after the second number in an array.

It is simple to find every number in the given Array

``````function isNumber(x) {
return typeof x === 'number';
}
var list = ['a', 'b', 1, 2, 3, 'c'];
console.log(list.filter(isNumber)); // [1, 2, 3]
``````

The `.filter` iterator returns every value that passes the given predicate. What if we wanted to know what the second number is in an array? We could filter and access element with index 1.

``````function nth(k, predicate, list) {
return list.filter(isNumber)[k];
}
var secondNumber = nth.bind(null, 1, isNumber);
console.log(secondNumber(list)); // 2
``````

This approach destroys the information about the position of the second number in the original list. What if I wanted to print first item after the second number? By filtering the list first, we lost the original positions.

## Counting predicates

Instead of making a new array right away, we can write a function that keeps count how many times a predicate returned true.

``````function nth(n, predicate) {
var k = 0;
return function () {
var result = predicate.apply(null, arguments);
if (result) {
k += 1;
}
return k === n;
};
}
``````

Instead of using `Array.prototype.filter` we can now use `Array.prototype.map` because we are interested where in the original list is the second number, not its value yet.

``````var list = ['a', 'b', 1, 2, 3, 'c'];
var secondNumber = nth(2, isNumber);
console.log(list.map(secondNumber));
// [ false, false, false, true, false, false ]
``````

Function `nth` mixes two aspects togehter: counting and predicate execution. I showed an example of splitting such function into smaller focused functions. Let us rewrite `nth` in terms of two simpler functions. First, the counter.

``````// keeps number of executions
function counter(n) {
console.assert(n > 0, 'invalid n to count to ' + n);
var k = 0;
return function () {
k += 1;
return k === n;
}
}
// example
var countTo2 = counter(2);
console.assert(!countTo2(), 'first');
console.assert(countTo2(), 'second');
console.assert(!countTo2(), 'after');
``````

The `nth` function becomes a simple composition

``````function nth(n, predicate) {
var counterToN = counter(n);
return function () {
var result = predicate.apply(null, arguments);
return result ? counterToN() : false;
};
}
var secondNumber = nth(2, isNumber);
var list = ['a', 'b', 1, 2, 3, 'c'];
console.log(list.map(secondNumber));
// [ false, false, false, true, false, false ]
``````

Using `counter` we can write other predicates, for example for finding items n positions after another predicate returns true.

``````function after(n, predicate) {
var countToN = counter(n);
var seenPositive;
return function () {
if (seenPositive) {
return countToN();
}
seenPositive = predicate.apply(null, arguments);
return false;
};
}
``````

A couple of examples

``````var list = ['a', 'b', 1, 2, 3, 'c'];
var firstAfter2ndNumber = after(1, nth(2, isNumber));
console.log(list.map(firstAfter2ndNumber));
[ false, false, false, false, true, false ]
var secondAfter2ndNumber = after(2, nth(2, isNumber));
console.log(list.map(secondAfter2ndNumber));
[ false, false, false, false, false, true ]
``````

Note that our predicate with built-in counter does NOT reset itself. Thus it can only be used once

``````var list = ['a', 'b', 1, 2, 3, 'c'];
var firstAfter2ndNumber = after(1, nth(2, isNumber));
console.log(list.map(firstAfter2ndNumber));
[ false, false, false, false, true, false ]
console.log(list.map(firstAfter2ndNumber));
[ false, false, false, false, false, false ]
``````

## Printing value

Once we have boolean list, we can find the actual value. Just take the first element where the predicate returns true

I probably will use this approach for flexible optional argument parsing.