How to check if a list contains a value in Clojure
Tags: tutorial, java, functional, learning
Published: 2020-07-06 06:50:48

---
title: How to check if a list contains a value in Clojure
published: true
description: 
tags: tutorial, java, functional, learning
cover_image: https://www.mednikov.tech/wp-content/uploads/2020/07/person-in-black-and-white-plaid-dress-shirt-using-mac-book-3740306.jpg
---
Recently I started to learn Clojure, and usually, my first phase is to complete small programming exercises. To practice Clojure I decided to solve some CodingBat problems. A common task here is to check, if an array does contain some value. The expected result should be a boolean value. When I moved to practical implementations, I realized how tricky can be a simple thing in Clojure.

In this post I would like to share with you some thoughts on how to check, that a list contains an element in Clojure. As almost any beginner I have started with _contains?_ method, however it may not be your best option. I will explain to you several solutions, including ones, that come from Java.

## What is wrong with contains? function?

This is an expected question. To explain it, let me take a simple exercise from CodingBat. For example, [array-1/has23](https://codingbat.com/prob/p171022). The problem statement asks us to return a boolean value, which reflects if the given array contains 2 or 3. Pretty simple, isn't it? Let start with _contains?_ function. Take a look on the following code snippet below:

```clojure
(defn has23 [numbers]
    (or (contains? numbers 2) (contains? numbers 3))
)

(println (has23 [2 5]))
(println (has23 [4 5]))
(println (has23 [1 3]))
```

What is wrong with this code? When you will execute it you will receive an output, similar to this:

```
false
false
false
```

But there are values - the first list has 2 and the last one has 3, why it is false? The answer is in the purpose of this method. _contains?_ returns a boolean value, which represents if a data structure contains a __key__. So, it works for associative data structures (like maps). For [lists](https://www.smashwords.com/books/view/1029860) a key is an index of an element. Because we have an array of 2 elements, it can't have an index 2 and moreover 3! As a result, this approach would not work. Hopefully, there are others.

## Using some

When you will search for the solution, most probably you will find [recommendations](https://insideclojure.org/2015/01/27/clojure-tips-contains/) to use _some_. It works fine with sequential data structures, like lists. This function takes two arguments: a predicate (logical condition) and a data structure itself. The return is a first matching element.

Let try it with an another exercise - [warmup-2/arrayFront9](https://codingbat.com/prob/p186031). The task here demands us to return true, if there is 9 in first 4 elements. Note, that I use _take_ function to get first 4 elements:

```clojure
(defn arrayFront9 [numbers]
    (some #{9} (take 4 numbers))
)

(println (arrayFront9 [1 2 9 3 4]))
```

The output of the code listing above is 

```
9
```

Now we will check result with a list, which does not have 9 among first four elements:

```clojure
(defn arrayFront9 [numbers]
    (some #{9} (take 4 numbers))
)

(println (arrayFront9 [1 2 3 4 9]))
```

In this case, the output is _nil_. This may lead to an [error](https://www.mednikov.tech/error-handling-webflux/), if another logic relies on this function, which can return a null value. Furthermore, we need to get a boolean result. Let refactor our solution:

```clojure
(defn arrayFront9 [numbers]
    (not= (some #{9} (take 4 numbers)) nil)
)

(println (arrayFront9 [1 2 9 3 4]))
(println (arrayFront9 [1 2 3 4 9]))
```

I added an assertion to check if the element is not null. In other words, if 9 does exist among first subsequence, it will be returned, otherwise the result will be null. So, I wrapped it around logical validation to return a boolean value. The output of this code is:

```
true
false
```

As expected!

## Go Java

In my previous post on [Clojure exception handling](https://www.mednikov.tech/exception-handling-in-clojure/), I stated that as Clojure runs on JVM it inherits a lot of from Java. That leads us to an another soltuion - using Java methods to work with collections. If you have read my article on [Java collections](https://www.mednikov.tech/understand-java-collections/), you may remember that we have two methods in our disposal:

* _contains_ = returns true if an element is presented in a collection
* _indexOf_ = returns an index of an element, or -1 in case of its absence

In this section we will observe, how to use them both.

### Contains

Let take the exercise called [array-1/no23](https://codingbat.com/prob/p175689). It is a mirror to what we have already solved in in a _has23_ example, but now we need to assure, that the list does not contain 2 or 3. In order to call Java methods in Clojure we utilize a concept of dot notation:

```clojure
(defn no23 [numbers]
    (not (or (.contains numbers 2) (.contains numbers 3)))
)

(println (no23 [5 4]))
(println (no23 [2 1]))
(println (no23 [4 3]))
```

When you will run this code snippet, you will receive an output like that:

```
true
false
false
```

Remember, that we are expected to find an absence of 2 and 3 in a list. This means, we need to negate a result of calling _.contains_ function.

### IndexOf

While looking for a solution, I have found an [interesting approach](https://stackoverflow.com/questions/3249334/test-whether-a-list-contains-a-specific-value-in-clojure). It is based on using _indexOf_ method. As you remember, this function checks for an element and returns its index or -1 (when an element is not in a list).

To illustrate this point let take again _arrayFront9_ exercise, but not we will refactor it to use _indexOf_. Take a look on my implementation below:

```clojure
(defn arrayFront9IndexOf [numbers]
    (not= (.indexOf (take 4 numbers) 9) -1)
)

(println (arrayFront9IndexOf [1 2 9 3 4]))
(println (arrayFront9IndexOf [1 2 3 4 9]))
```

The result of an execution will be following:

```
true
false
```

We use negation _not=_ in a similar way, like with _some_. We need to validate, that a result from calling _indexOf_ function is not equal to -1 (that means an absense of 9). Any other value corresponds to a presence.

That is all for this post. Hope, that it helped you in a some manner. If you have questions regarding a topic of how to check if a list contains a value in Clojure, you can ask them in comments below or [contact me](https://www.mednikov.tech/contact-me/).