DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Reversing an Array: An Exploration of Array Manipulation
  • Unlocking the Potential of Binary Search Trees with C# Programming
  • Sliding Window
  • Build Your Own Shopping Cart With React Hooks

Trending

  • Throughput vs Goodput: The Performance Metric You Are Probably Ignoring in LLM Testing
  • Architecting Petabyte-Scale Hyperspectral Pipelines on AWS
  • Stop Writing Dialect-Specific SQL: A Unified Query Builder for Node.js
  • S3 Vectors: How to Build a RAG Without a Vector Database
  1. DZone
  2. Data Engineering
  3. Data
  4. How to Check if A List Contains a Value in Clojure

How to Check if A List Contains a Value in Clojure

This article goes over four different methods for determining whether a list has a specific value using Clojure.

By 
Yuri Mednikov user avatar
Yuri Mednikov
·
Jul. 06, 20 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
13.6K Views

Join the DZone community and get the full member experience.

Join For Free

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. 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 at the following code snippet below:

Clojure
 




x


 
1
(defn has23 [numbers]
2
    (or (contains? numbers 2) (contains? numbers 3))
3
)
4

          
5
(println (has23 [2 5]))
6
(println (has23 [4 5]))
7
(println (has23 [1 3]))
8

          


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

Plain Text
 




x


 
1
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 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 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. 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
 




x


 
1
(defn arrayFront9 [numbers]
2
    (some #{9} (take 4 numbers))
3
)
4

          
5
(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
 




x


 
1
(defn arrayFront9 [numbers]
2
    (some #{9} (take 4 numbers))
3
)
4

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


In this case, the output is nil. This may lead to an error, 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
 




x


 
1
(defn arrayFront9 [numbers]
2
    (not= (some #{9} (take 4 numbers)) nil)
3
)
4

          
5
(println (arrayFront9 [1 2 9 3 4]))
6
(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 sub sequence, 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:

Plain Text
 




xxxxxxxxxx
1


 
1
true false


As expected!

Go Java

In my previous post on Clojure exception handling, I stated that as Clojure runs on JVM it inherits a lot of from Java. That leads us to an another solution – using Java methods to work with collections. If you have read my article on 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. It is a mirror to what we have already solved in has23, 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
 




x


 
1
(defn no23 [numbers]
2
    (not (or (.contains numbers 2) (.contains numbers 3)))
3
)
4

          
5
(println (no23 [5 4]))
6
(println (no23 [2 1]))
7
(println (no23 [4 3]))


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

Plain Text
 




xxxxxxxxxx
1


 
1
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. 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
 




x


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

          
5
(println (arrayFront9IndexOf [1 2 9 3 4]))
6
(println (arrayFront9IndexOf [1 2 3 4 9]))


The result of an execution will be following:

Plain Text
 




xxxxxxxxxx
1


 
1
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 absence of 9). Any other value corresponds to a presence.

Clojure Listing (computer) Data structure Element Plain text

Published at DZone with permission of Yuri Mednikov. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Reversing an Array: An Exploration of Array Manipulation
  • Unlocking the Potential of Binary Search Trees with C# Programming
  • Sliding Window
  • Build Your Own Shopping Cart With React Hooks

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook