Return first non-empty / empty value?

I have 2 bindings, I call the path and callback.

What I'm trying to do is return the first nonempty one. In javascript, it will look like this:

var final = path || callback || ""; 

How to do it in clojure?

I looked at the "some" functions, but I cannot figure out how to combine compjure.string / blank validation. I currently have it as a test that does not work. In this case, it should return zero, I think.

 (some (clojure.string/blank?) ["1" "2" "3"]) 

In this case, he must return 2

 (some (clojure.string/blank?) ["" "2" "3"]) 
+4
source share
5 answers
 (first (filter (complement clojure.string/blank?) ["" "a" "b"])) 

Edit: As pointed out in the comments, (filter (complement p) ...) can be rewritten as (remove p ...) :

 (first (remove clojure.string/blank? ["" "a" "b"])) 
+6
source

If you want the first non-empty string of a sequence, you can use something like this:

 (first (filter #(not (clojure.string/blank? %)) ["" "2" "3"])) 

This will return 2

What I do not understand is your first example using some function, you said that it should return zero, but the first non-empty line is "1".

+2
source

This is how you would use the some function:

 (some #(when-not (empty? %) %) ["" "foo" ""]) "foo" (some #(when-not (empty? %) %) ["bar" "foo" ""]) "bar" 

As others noted, filter is another option:

 (first (filter #(not (empty? %)) ["" "" "foo"]) "foo" 

A third option would be to use recursion:

 (defn first-non-empty [& x] (let [[y & z] x] (if (not (empty? y)) y (when z (recur z))))) (first-non-empty "" "bar" "") "bar" (first-non-empty "" "" "foo") "foo" (first-non-empty "" "" "") nil 

Did I use empty? instead of blank? to save when entering text, but the only difference is how to handle spaces.

+1
source

It was hard for me to say exactly what you wanted, so this is my understanding of what you are trying to do.

In my case, I wanted to find if there was no element in one report in the second report. The match returned nil, and the mismatch returned an actual element that did not match.

The following functions complete the comparison of the displayed value with the key.

Using something like find-first , probably what you want to do.

 (defn find-first "This is a helper function that uses filter, a comparision value, and stops comparing once the first match is found. The actual match is returned, and nil is returned if comparision value is not matched." [pred col] (first (filter pred col))) (defn str-cmp "Takes two strings and compares them. Returns 0 if a match; and nil if not." [str-1 str-2 cmp-start-pos substr-len] (let [computed-str-len (ret-lowest-str-len str-1 str-2 substr-len) rc-1 (subs str-1 cmp-start-pos computed-str-len) rc-2 (subs str-2 cmp-start-pos computed-str-len)] (if (= 0 (compare rc-1 rc-2)) 0 nil))) (defn cmp-one-val "Return nil if first key match found, else the original comparision row is returned. cmp-row is a single sequence of data from a map. i cmp-key is the key to extract the comparision value. cmp-seq-vals contain a sequence derived from one key in a sequence of maps. cmp-start and substr-len are start and stop comparision indicies for str-cmp." [cmp-row cmp-key cmp-seq-vals cmp-start substr-len] (if (find-first #(str-cmp (cmp-key cmp-row) %1 cmp-start substr-len) cmp-seq-vals) nil cmp-row)) 
0
source

If you are lucky to have "empty values" represented by nil and / or false, you can use:

 (or nil false "a" "b") 

Which will return "a" .

As an example equivalent to your JavaScript, do the following:

 (let [final (or path callback "")] (println final)) 
0
source

Source: https://habr.com/ru/post/1500992/


All Articles