You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
</code></pre><h3id="contains">contains?</h3><p><code>contains</code> returns true if the provided <em>key</em> is present in a collection. <code>contains</code> is similar to <code>get</code> in that vectors treat the key as an index. <code>contains</code>will always return false for lists.</p><pre><codeclass="klipse-clojure nohighlight">(contains? {:a 1 :b 2 :c 3} :c)
324
+
</code></pre><h3id="contains">contains?</h3><p><code>contains?</code> returns true if the provided <em>key</em> is present in a collection. <code>contains?</code> is similar to <code>get</code> in that vectors treat the key as an index. <code>contains?</code>does not work for lists.</p><pre><codeclass="klipse-clojure nohighlight">(contains? {:a 1 :b 2 :c 3} :c)
325
325
;; ⇒ true
326
326
</code></pre><pre><codeclass="klipse-clojure nohighlight">;; true if index 2 exists
327
327
(contains? ["John" "Mary" "Paul"] 2)
@@ -405,6 +405,43 @@ <h2>Language: Collections and Sequences</h2>
405
405
returns falsey. This is because if the item is present in the set it is returned.</p><pre><codeclass="klipse-clojure nohighlight">(remove #{:nothing :something nil false}
</code></pre><h3id="sort-sort-by">sort, sort-by</h3><p><code>sort</code> and <code>sort-by</code> are flexible higher-order functions for sorting sequential collections like lists and vectors. Both take an optional <code>Comparator</code> which defaults to <code>compare</code>, and <code>sort-by</code> takes a function that transforms each value before comparison.</p><h4id="sort">sort</h4><p><code>sort</code> using the default comparator can handle numbers...</p><pre><codeclass="klipse-clojure nohighlight">(sort [0.0 -1 1.3 nil 0.18 7])
409
+
;; ⇒ (nil -1 0.0 0.18 1.3 7)
410
+
</code></pre><p>... and strings</p><pre><codeclass="klipse-clojure nohighlight">(sort ["the case matters" "lexicographic ordering" "The case matters" nil "%%"])
411
+
;; ⇒ (nil "%%" "The case matters" "lexicographic ordering" "the case matters")
412
+
</code></pre><p>... and vectors whose elements are element-wise comparable</p><pre><codeclass="klipse-clojure nohighlight">(sort [[1 "banana"] [1 "apple"] [0 "grapefruit"]])
413
+
;; ⇒ ([0 "grapefruit"] [1 "apple"] [1 "banana"])
414
+
</code></pre><p>... but it can't "cross" types.</p><pre><codeclass="klipse-clojure nohighlight">; `compare` doesn't know how to compare Strings and numbers
415
+
(sort [5 1.0 "abc"])
416
+
;; Execution error (ClassCastException)...
417
+
;; class java.lang.Double cannot be cast to class java.lang.String
418
+
</code></pre><p>In order to do more complicated sorting, we can create our own <code>Comparator</code>. There's a wealth of information
419
+
about comparators in the <ahref="https://www.clojure.org/guides/comparators">clojure.org comparators guide</a>, but for now, one possible comparator is a
420
+
function that takes two arguments and returns a negative, positive, or zero integer when the first argument is 'less than', 'greater than', or equal to (respectively) the second argument.</p><pre><codeclass="klipse-clojure nohighlight">(letfn [(strings-before-numbers
421
+
[x y]
422
+
(cond
423
+
; string is 'less than' number
424
+
(and (string? x) (number? y)) -1
425
+
; number is 'greater than' string
426
+
(and (number? x) (string? y)) 1
427
+
; otherwise we can use `compare`
428
+
:else (compare x y)))]
429
+
(sort strings-before-numbers [1 0.0 nil "abc"]))
430
+
;; ⇒ (nil "abc" 0.0 1)
431
+
</code></pre><p>A common way to reverse a sort is to <code>comp</code> the <code>-</code> function with a comparator that returns a number, which effectively
</code></pre><h4id="sort-by">sort-by</h4><p><code>sort-by</code> takes a <code>keyfn</code> function and uses <code>sort</code> based on the result of appying <code>keyfn</code> to the values to be sorted.
435
+
It's typically a good candidate for sorting collections of maps/records/objects.</p><pre><codeclass="klipse-clojure nohighlight">(sort-by :last [{:first "Fred" :last "Mertz"}
436
+
{:first "Lucy" :last "Ricardo"}
437
+
{:first "Ricky" :last "Ricardo"}
438
+
{:first "Ethel" :last "Mertz"}])
439
+
;; ⇒ ({:first "Fred", :last "Mertz"}
440
+
;; {:first "Ethel", :last "Mertz"}
441
+
;; {:first "Lucy", :last "Ricardo"}
442
+
;; {:first "Ricky", :last "Ricardo"})
443
+
</code></pre><p>Because <code>compare</code> compares vectors element-wise, it's possible to use <code>juxt</code> to effectively sort by a few values without a custom comparator.</p><p>Sort the strings from shortest to longest, and then alphabetically (ignoring case):</p><pre><codeclass="klipse-clojure nohighlight">(sort-by (juxt count clojure.string/lower-case) ["Alpha" "bravo" "Charlie" "Delta" "echo"])
444
+
;; ⇒ ("echo" "Alpha" "bravo" "Delta" "Charlie")
408
445
</code></pre><h3id="iterate">iterate</h3><p><code>iterate</code> takes a function and an initial value, returns the result of
409
446
applying the function on that initial value, then applies the function
410
447
again on the resultant value, and repeats forever, lazily. Note that the
0 commit comments