select first item of a collection that satisfies given predicate in clojure - clojure

Is there a function in clojure that (given a predicate and a collection),
selects the first item that satisfies the given predicate and stop the iteration?
for example:
(select-first #(> % 10) (range))
=> 11
If not, maybe someone could hint me about an idiomatic implementation

There are multiple possibilities.
some
some returns the first non-nil value its predicate returns.
(some #(when (> % 10) %) (range)) ;; => 11
filter + first
filter retains those elements that match a predicate, first retrieves the first of them.
(first (filter #(> % 10) (range))) ;; => 11
remove + first
If you want to find the first element that does not match your predicate, remove is your friend:
(first (remove #(<= % 10) (range))) ;; => 11
Or with some:
(some #(when-not (<= % 10) %) (range)) ;; => 11
So, that's it, I guess.

Use filter and first
user=> (->> (range) (filter #(> % 10)) first)
11
user=> (first (filter #(> % 10) (range)))
11

Related

Need the first 10 multiples of any number in Clojure

We've been given a task to print the first ten multiples of any number for which we have written the below code. It is throwing an error. In simple words, if n is 2 then we need to create a table of 2's till 10.
(defn multiples [n]
(while ( n < 11)
(println( n * n))
(swap! n inc)))
(def n (Integer/parseInt (clojure.string/trim (read-line))))
(multiples n)
With this, we're getting the error:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.
(defn multiples [n]
(map #(* n %) (range 1 (+ 10 1))))
user=> (multiples 1)
;; => (1 2 3 4 5 6 7 8 9 10)
user=> (multiples 2)
;; => (2 4 6 8 10 12 14 16 18 20)
The resulting list you can loop over and println each of the elements.
(for [i (multiples 2)]
(println i))
;; or:
(map println (multiples 2)) ;; though one usually doesn't apply
;; `map` on side effect functions ...
To improve your own construct:
You, coming from an imperative language, try to work with mutations.
That is very un-idiomatic clojure.
However, by declaring a value atom, you can access using the # operator to its place. And mutate the variable's value.
(defn multiples [n]
(let [i (atom 1)] ;; i is an atom
(while (< #i 11) ;; #i is the value saved into i
(println (* #i n))
(swap! i inc)))) ;; and correctly you can increase the value
With this multiples, you can also print the values.
You can't apply swap! to normal variables, only to atoms.
while loops one should apply only if number of elements not known.
In this case, one knows very well, when to stop. So use rather
a for loop.
(defn multiples [n]
(for [i (range 1 11)]
(println (* i n))))
Look at what iterate function does here
(defn multiples-of [n]
(iterate (partial * n) n))
(def ten-multiples-of-ten
(take 10 (multiples-of 10)))
EDIT: I misread the author of the question, I believe he wants to just generate a sequence of squares. Here is one way using transducers, cause why not ;)
(def xf
(comp
(map inc)
(map #(* % %))))
(defn first-n-squares [n]
(into [] xf (take n (range))))
You can use recur in a loop:
(defn multiples [n]
(if (< n 11)
(do ; then
(println (* n n))
(recur (inc n)))
nil)) ; else return nil
Running this by invoking
(multiples 1)
in a REPL will produce
1
4
9
16
25
36
49
64
81
100
nil

Building a lazy, impure id generator

I'd like to know how to create an infinite, impure sequence of unique values in Clojure.
(def generator ...) ; def, not defn
(take 4 generator) ; => (1 2 3 4)
(take 4 generator) ; => (5 6 7 8). note the generator's impurity.
I think that such a design could be more convenient than e.g. wrapping a single integer value into a reference type and increment it from its consumers, as:
The proposed approach reduces the implementation details to a single point of change: the generator. Otherwise all the consumers would have to care about both the reference type (atom), and the concrete function that provides the next value (inc)
Sequences can take advantage many clojure.core functions. 'Manually' building a list of ids out of an atom would be a bit bulky: (take 4 (repeatedly #(swap! _ inc)))
I couldn't come up with a working implementation. Is it possible at all?
You can wrap a lazy sequence around an impure class (like a java.util.concurrent.atomic.AtomicLong) to create an id sequence:
(def id-counter (java.util.concurrent.atomic.AtomicLong.))
(defn id-gen []
(cons
(.getAndIncrement id-counter)
(lazy-seq
(id-gen))))
This works, but only if you don't save the head of the sequence. If you create a var that captures the head:
(def id-seq (id-gen))
Then call it repeatedly, it will return ids from the beginning of the sequence, because you've held onto the head of the sequence:
(take 3 id-seq)
;; => (0 1 2)
(take 3 id-seq)
;; => (0 1 2)
(take 3 id-seq)
;; => (0 1 2)
If you re-create the sequence though, you'll get fresh values because of the impurity:
(take 3 (id-gen))
;; (3 4 5)
(take 3 (id-gen))
;; (6 7 8)
(take 3 (id-gen))
;; (9 10 11)
I only recommend doing the following for educational purposes (not production code), but you can create your own instance of ISeq which implements the impurity more directly:
(def custom-seq
(reify clojure.lang.ISeq
(first [this] (.getAndIncrement id-counter))
(next [this] (.getAndIncrement id-counter))
(cons [this thing]
(cons thing this))
(more [this] (cons
(.getAndIncrement id-counter)
this))
(count [this] (throw (RuntimeException. "count: not supported")))
(empty [this] (throw (RuntimeException. "empty: not supported")))
(equiv [this obj] (throw (RuntimeException. "equiv: not supported")))
(seq [this] this)))
(take 3 custom-seq)
;; (12 13 14)
(take 3 custom-seq)
;; (15 16 17)
I had a fun time discovering something during answering your question. The first thing that occured to me was that perhaps, for whatever ultimate goal you need these IDs for, the gensym function might be helpful.
Then, I thought "well hey, that seems to increment some impure counter to generate new IDs" and "well hey, what's in the source code for that?" Which led me to this:
(. clojure.lang.RT (nextID))
Which seems to do what you need. Cool! If you want to use it the way you suggest, then I would probably make it a function:
(defn generate-id []
(. clojure.lang.RT (nextID)))
Then you can do:
user> (repeatedly 5 generate-id)
=> (372 373 374 375 376)
I haven't yet tested whether this will produce always unique values "globally"--I'm not sure about terminology, but I'm talking about when you might be using this generate-id function from within different threads, but want to still be sure that it's producing unique values.
this is another solution, maybe:
user=> (defn positive-numbers
([] (positive-numbers 1))
([n] (cons n (lazy-seq (positive-numbers (inc n))))))
#'user/positive-numbers
user=> (take 4 (positive-numbers))
(1 2 3 4)
user=> (take 4 (positive-numbers 5))
(5 6 7 8)
A way that would be more idiomatic, thread-safe, and invites no weirdness over head references would be to use a closure over one of clojures built in mutable references. Here is a quick sample I worked up since I was having the same issue. It simply closes over a ref.
(def id-generator (let [counter (ref 0)]
(fn [] (dosync (let [cur-val #counter]
(do (alter counter + 1)
cur-val))))))
Every time you call (id-generator) you will get the next number in the sequence.
Here's another quick way:
user> (defn make-generator [& [ii init]]
(let [a (atom (or ii 0 ))
f #(swap! a inc)]
#(repeatedly f)))
#'user/make-generator
user> (def g (make-generator))
#'user/g
user> (take 3 (g))
(1 2 3)
user> (take 3 (g))
(4 5 6)
user> (take 3 (g))
(7 8 9)
This is hack but it works and it is extremely simple
; there be dragons !
(defn id-gen [n] (repeatedly n (fn [] (hash #()))))
(id-gen 3) ; (2133991908 877609209 1060288067 442239263 274390974)
Basically clojure creates an 'anonymous' function but since clojure itselfs needs a name for that, it uses uniques impure ids to avoid collitions. If you hash a unique name then you should get a unique number.
Hope it helps
Creating identifiers from an arbitrary collection of seed identifiers:
(defonce ^:private counter (volatile! 0))
(defn- next-int []
(vswap! counter inc))
(defn- char-range
[a b]
(mapv char
(range (int a) (int b))))
(defn- unique-id-gen
"Generates a sequence of unique identifiers seeded with ids sequence"
[ids]
;; Laziness ftw:
(apply concat
(iterate (fn [xs]
(for [x xs
y ids]
(str x y)))
(map str ids))))
(def inf-ids-seq (unique-id-gen (concat (char-range \a \z)
(char-range \A \Z)
(char-range \0 \9)
[\_ \-])))
(defn- new-class
"Returns an unused new classname"
[]
(nth inf-ids-seq (next-int)))
(repeatedly 10 new-class)
Demonstration:
(take 16 (unique-id-gen [\a 8 \c]))
;; => ("a" "8" "c" "aa" "a8" "ac" "8a" "88" "8c" "ca" "c8" "cc" "aaa" "aa8" "aac" "a8a")

How To Capture "Row" Number

My question is how can I capture the index of the vector row where a match occurred? In the code below, what am I doing wrong?
I have a vector of vectors
(def v1 [[44 2 3 4 5][1 6 7 5 10][11 12 13 14 15]])
a column index, and a comparison value
(def cmp-val1 11)
(def col-idx 0)
I want to return the row index where a comparison returned true. With col-idx = 0 and cmp-val1 = 11, I should see (first row-num) return 2, and it is returning 1.
(defn ret-match-row
"Return the index of the row, in which the cmp-val is found.
It is okay to increment 0."
[in-seq cmp-val col-idx]
(let [rn 0]
(let [row-num
(for [seq-row in-seq
:let [local-row-num (inc rn)]
:when (= cmp-val (nth seq-row col-idx nil))]
local-row-num)]
(first row-num))))
From lein repl:
bene-csv.core=> (ret-match-row v1 cmp-val1 col-idx)
1
=> (defn ret-match-row
[coll cmp idx]
(keep-indexed (fn [i v] (if (= cmp (get v idx)) i)) coll))
=> (ret-match-row v1 11 0)
(2)
A flexible answer comes from separating this into three distinct problems and composing them.
creating the data you seek
finding the data you want
presenting the way it should look.
first we number the rows by adding row numbers to them
(map vector v1 (range))
then filter out the rows not containing the number you want:
(filter (fn [[data index]] (some #{11} data)) (map vector v1 (range)))
> ([[11 12 13 14 15] 2])
here i used the trick that sets are functions that test their input for inclusion in the set which allows this to test for multiple values:
(filter (fn [[data index]] (some #{11 44} data)) (map vector v1 (range)))
> ([[44 2 3 4 5] 0] [[11 12 13 14 15] 2])
then since you only want to know where it matched and not what matched we filter that out:
(map second (filter (fn [[data index]] (some #{11 44} data)) (map vector v1 (range))))
> (0 2)
to wrap this into a nice function we write out the steps:
(defn with-row-numbers [col] (map vector col (range)))
(defn find-my-rows [rows goals]
(filter (fn [[data index]] (some (set goals) data)) rows))
(defn present-rows [rows] (map second rows))
and then compose them:
(defn ret-match-row [data rows]
(-> data
(with-row-numbers)
(find-my-rows rows)
(present-rows)))
(ret-match-row v1 [11])
(2)
sorry i couldn't help making it work with multiple values, its a habit.
(ret-match-row v1 [11 15 44])
> (0 2)
There may be other ways to do what your'e asking, but you can use a loop/recur to achieve the iteration you're after:
(defn ret-match-row [rows val col-idx]
(loop [[row & rows] rows
pos 0]
(cond
(not row)
nil
(= val (nth row col-idx))
pos
:not-found
(recur rows (inc pos)))))
(ret-match-row [[44 2 3 4 5]
[1 6 7 8 10]
[11 12 13 14 15]]
11
0)
;; => 2
You're also running into Clojure's immutability - the (inc rn) is not actually modifying rn. The loop / recur solution uses inc as well, but it passes the result of inc to the next iteration of the loop.
Clojure's for (list comprehension) form also will loop over all of the values in the sequence, resulting in a new sequence -- which is most likely not what you want. Even if you made the for loop do what you want, it will find all the matches, not just the first. The loop / recur example stops at the first match.
My take, using
clojure.contrib.seq find-first, indexed:
(defn ret-match-row [rows val col-idx]
(first
(find-first #(= val (nth (second %) col-idx))
(indexed rows))))

Return first item in a map/list/sequence that satisfies a predicate

I am looking for a function that returns the first element in a sequence for which an fn evaluates to true. For example:
(first-map (fn [x] (= x 1)) '(3 4 1))
The above fake function should return 1 (the last element in the list). Is there something like this in Clojure?
user=> (defn find-first
[f coll]
(first (filter f coll)))
#'user/find-first
user=> (find-first #(= % 1) [3 4 1])
1
Edit: A concurrency. :) No. It does not apply f to the whole list. Only to the elements up to the first matching one due to laziness of filter.
In your case, the idiom is
(some #{1} [1 2 3 4])
How it works: #{1} is a set literal. A set is also a function evaluating to its arg if the arg is present in the set and to nil otherwise. Any set element is a "truthy" value (well, except for a boolean false, but that's a rarity in a set). some returns the return value of the predicate evaluated against the first collection member for which the result was truthy.
I tried several methods mentioned in this thread (JDK 8 and Clojure 1.7), and did some benchmark tests:
repl> (defn find-first
[f coll]
(first (filter f coll)))
#'cenx.parker.strategies.vzw.repl/find-first
repl> (time (find-first #(= % 50000000) (range)))
"Elapsed time: 5799.41122 msecs"
50000000
repl> (time (some #{50000000} (range)))
"Elapsed time: 4386.256124 msecs"
50000000
repl> (time (reduce #(when (= %2 50000000) (reduced %2)) nil (range)))
"Elapsed time: 993.267553 msecs"
50000000
The results show that reduce way may be the most efficient solution as in clojure 1.7.
In 2016 there was a patch submitted to clojure core that added an efficient shortcut for (first (filter pred coll)) idiom, it was called seek.
The implementation avoided problems in herent with both the (first (filter)) and (some #(when (pred))) alternatives. That is, it works efficiently with chunked sequences and plays nice with nil? and false? predicates.
Patch:
(defn seek
"Returns first item from coll for which (pred item) returns true.
Returns nil if no such item is present, or the not-found value if supplied."
{:added "1.9" ; note, this was never accepted into clojure core
:static true}
([pred coll] (seek pred coll nil))
([pred coll not-found]
(reduce (fn [_ x]
(if (pred x)
(reduced x)
not-found))
not-found coll)))
Examples:
(seek odd? (range)) => 1
(seek pos? [-1 1]) => 1
(seek pos? [-1 -2] ::not-found) => ::not-found
(seek nil? [1 2 nil 3] ::not-found) => nil
Eventually the patch was rejected:
Upon review, we've decided that we do not wish to include this. Use of linear search (and in particular nested linear search) leads to poor performance - often it's better to use other kinds of data structures and that's why this functionality has not been included in the past. ~Alex Miller 12/May/17 3:34 PM
I think some is the best tool for the job:
(some #(if (= % 1) %) '(3 4 1))
Using drop-while instead of filter should address "over-application" of f for chunked sequences:
(defn find-first [f coll]
(first (drop-while (complement f) coll)))
;;=> #'user/find-first
(find-first #(= % 1) [3 4 1])
;;=> 1
The way I do this in clojure is sort like you might do it in Scheme.
(defn call-with-found
"Call the given predicate, pred, on successive elements of the collection
until the first time pred returns a truthy value, at which time if-found
is called with that element of the collection, and call-with-found returns
the return value of if-found. If no such element of collection is found
(including if collection is empty) then the value if-not-found (defaulting
to false) is returned."
([pred coll & {:keys [if-found if-not-found]
:or {if-found (constantly true)
if-not-found false}}]
(reduce (fn [_ item]
(if (pred item)
(reduced (if-found item))
if-not-found)) if-not-found coll)))
The function call-with-found is called with a predicate and a collection. We search the collection until we find an element which satisfies the predicate, at which point we call the if-found continuation with that value, else we return the if-not-found value.

In Clojure, is it possible to define an anonymous function within an anonymous function?

For example, solving the following problem
http://projecteuler.net/problem=5
I came up with the following solution
(defn div [n] (= 0 (reduce + (map #(mod n %) (range 1 21)))))
(take 1 (filter #(= true (div %)) (range 20 1e11 20)))
Suppose for some golfing fun I wish to merge the first line as an anonymous function into the second line. Does the language support this?
Yes it does, but you cannot nest the #() reader-macro forms, you have to use the (fn) form.
For example:
(#(#(+ %1 %2) 1) 2)
does not work, because there's no way to refer to the arguments of the outer anonymous functions. This is read as the outer function taking two arguments and the inner function taking zero arguments.
But you can write the same thing with (fn...)s:
user=> (((fn [x] (fn [y] (+ x y))) 1) 2)
3
You can also use the #() form for one of the two anonymous functions, e.g:
user=> (#((fn [x] (+ x %)) 1) 2)
3
So you can inline your div function like this (notice that we had to change the #() form passed to map to a (fn) form):
#(= true (= 0 (reduce + (map (fn [x] (mod % x)) (range 1 21)))))
You could rewrite your solution in a much simpler and more efficient way (x2 faster!)
(defn div [n] (every? #(= 0 (mod n %)) (range 1 21)))
(take 1 (filter div (range 20 1e11 20)))
The reason it is more efficient is because every? wouldn't traverse the whole list but rather stop when one of the element of the list is false.