# Functional programming: Return first truthy result of calling a list of different functions with a specific argument

While Ramda's `anyPass`

is similar in spirit, it simply returns a boolean if any of the functions yield true. Ramda (disclaimer: I'm a Ramda author) does not have this exact function. If you think it belongs in Ramda, please feel free to raise an issue or create a pull request for it. We can't promise that it would be accepted, but we can promise a fair hearing.

Scott Christopher demonstrated what is probably the cleanest Ramda solution.

One suggestion that hasn't been made yet is a simple recursive version, (although Scott Christopher's `lazyReduce`

is some sort of kin.) Here is one technique:

```
const firstTruthy = ([fn, ...fns], ...args) =>
fn == undefined
? null
: fn (...args) || firstTruthy (fns, ...args)
const functions = [
(input) => input % 3 === 0 ? 'multiple of 3' : false,
(input) => input * 2 === 8 ? 'times 2 equals 8' : false,
(input) => input + 2 === 10 ? 'two less than 10' : false
]
console .log (firstTruthy (functions, 3)) // 'multiple of 3'
console .log (firstTruthy (functions, 4)) // 'times 2 equals 8'
console .log (firstTruthy (functions, 8)) // 'two less than 10'
console .log (firstTruthy (functions, 10)) // null
```

I would probably choose to curry the function, either with Ramda's `curry`

or manually like this:

```
const firstTruthy = ([fn, ...fns]) => (...args) =>
fn == undefined
? null
: fn (...args) || firstTruthy (fns) (...args)
// ...
const foo = firstTruthy (functions);
[3, 4, 8, 10] .map (foo) //=> ["multiple of 3", "times 2 equals 8", "two less than 10", null]
```

Alternatively, I might use this version:

```
const firstTruthy = (fns, ...args) => fns.reduce((a, f) => a || f(...args), null)
```

(or again a curried version of it) which is very similar to the answer from Matt Terski, except that the functions here can have multiple arguments. Note that there is a subtle difference. In the original and the answer above, the result of no match is `null`

. Here it is the result of the last function if none of the other were truthy. I imagine this is a minor concern, and we could always fix it up by adding a `|| null`

phrase to the end.

You could use `Array#some`

with a short circuit on a truthy value.

```
const
firstTruthy = (functions, data) => {
let result;
functions.some(fn => result = fn(data));
return result || null;
},
functions = [
input => input % 3 === 0 ? 'multiple of 3' : false,
input => input * 2 === 8 ? 'times 2 equals 8' : false,
input => input + 2 === 10 ? 'two less than 10' : false
];
console.log(firstTruthy(functions, 3)); // 'multiple of 3'
console.log(firstTruthy(functions, 4)); // 'times 2 equals 8'
console.log(firstTruthy(functions, 8)); // 'two less than 10'
console.log(firstTruthy(functions, 10)); // null
```

Ramda has a way of short-circuiting `R.reduce`

(and a couple of others) using the `R.reduced`

function to indicate that it should stop iterating through the list. This not only avoids applying further functions in the list, but also short-circuits iterating further through the list itself which can be useful if the list you are working with is potentially large.

```
const firstTruthy = (fns, value) =>
R.reduce((acc, nextFn) => {
const nextVal = nextFn(value)
return nextVal ? R.reduced(nextVal) : acc
}, null, fns)
const functions = [
(input) => input % 3 === 0 ? 'multiple of 3' : false,
(input) => input * 2 === 8 ? 'times 2 equals 8' : false,
(input) => input + 2 === 10 ? 'two less than 10' : false
]
console.log(
firstTruthy(functions, 3), // 'multiple of 3'
firstTruthy(functions, 4), // 'times 2 equals 8'
firstTruthy(functions, 8), // 'two less than 10'
firstTruthy(functions, 10) // null
)
```

`<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.min.js"></script>`

An alternative option is to create a "lazy" version of `reduce`

which only continues if you apply the function passed as the accumulated value which continues iterating recursively through the list. This gives you control inside the reducing function to short-circuit by *not* applying the function that evaluates the rest of the values in the list.

```
const lazyReduce = (fn, emptyVal, list) =>
list.length > 0
? fn(list[0], () => lazyReduce(fn, emptyVal, list.slice(1)))
: emptyVal
const firstTruthy = (fns, value) =>
lazyReduce((nextFn, rest) => nextFn(value) || rest(), null, fns)
const functions = [
(input) => input % 3 === 0 ? 'multiple of 3' : false,
(input) => input * 2 === 8 ? 'times 2 equals 8' : false,
(input) => input + 2 === 10 ? 'two less than 10' : false
]
console.log(
firstTruthy(functions, 3), // 'multiple of 3'
firstTruthy(functions, 4), // 'times 2 equals 8'
firstTruthy(functions, 8), // 'two less than 10'
firstTruthy(functions, 10) // null
)
```