# Simplify loop using any?, all? and none?

by Axel Kee
23 September 2021
Ruby has some useful methods for enumerable (Array, Hash, etc), this post will talk about usage of any?, all?, and none?.

For examples used on this post, an **Order** model might have many **Payment** model (customer can pay order using split payments).

## any?

To check if an order has any paid payments, a loop-based implementation might look like this :

```
has_paid_payment = false
order.payments.each do |payment|
if payment.status == "paid"
# one of the payment is paid
has_paid_payment = true
break
end
end
if has_paid_payment
# ...
end
```

We can simplify the code above using **any?** like this :

```
if order.payments.any?{ |payment| payment.status == 'paid'}
# this will be executed if there is at least one paid payment
end
```

**any?** method can take in a block, and it will return true if the block ever returns a value that is not false or nil. (ie. true, or 123, or “abc”)

If no block is supplied, it will perform a self check for the elements:

```
order.payments.any?
# is equivalent to
order.payments.any? { |payment| payment }
```

## all?

To check if all payments has been paid for an order, a loop-based implementation might look like this:

```
fully_paid = true
order.payments.each do |payment|
if payment.status != "paid"
# one of the payment is not paid, hence not fully paid
fully_paid = false
break
end
end
if fully_paid
# ...
end
```

We can simplify the code above using **all?** like this :

```
if order.payments.all?{ |payment| payment.status == 'paid'}
# this will be executed if all payments are paid
end
```

**all?** method can take in a block, and it will return true if the block **never** returns a value that is false or nil for all of the elements.

If no block is supplied, it will perform a self check for the elements:

```
order.payments.all?
# is equivalent to
order.payments.all? { |payment| payment }
```

## none?

This is the opposite of **all?**.

**none?** method accepts a block, and only returns true if the block **never returns true** for all elements.

```
if order.payments.none? { |payment| payment.status == 'paid' }
# this will be executed if there is no paid payment for the order
end
```

If no block is supplied, it will perform a self check for the elements:

```
order.payments.none?
# is equivalent to
order.payments.none? { |payment| payment }
```

By utilizing any?, all? and none?, we can remove the usage of loop and make it more readable.

# Reference

Ruby doc on enumeration