简体   繁体   中英

Remove all substrings in first-array that match elements in second-array

The Quest

Remove every substring in first-array for every string in second-array that matches.

What is the best way to do it in Clojure?

Example:

first-array: ["Adam" "Goolan" "silly"]

second-array: [ "a" "oo" "ll"]

result: ["Adm" "Gln" "siy"]

Note that the result should be the same if

second-array: [ "oo" "ll" "a"]

If it is by matched elements (ie first item in first matches first item in second and so on):

> (defn the-quest [xs ys] 
    (map #(clojure.string/replace (first %1) (second %1) "") (map vector xs ys)))
#'sandbox1427/the-quest
> (the-quest ["Adam" "Goolan" "silly"] ["a" "oo" "ll"])
("Adm" "Glan" "siy")

See @Lee's comment below:

> (map #(clojure.string/replace %1 %2 "") ["Adam" "Goolan" "silly"] ["a" "oo" "ll"])
("Adm" "Glan" "siy")
>  

Note - the above courtesy of http://www.tryclj.com/

With any-to-any matching:

user=> (defn repl-all [x ys] 
  #_=>    (reduce #(clojure.string/replace %1 %2 "") x ys))

user=> (defn the-quest [xs ys]
  #_=>    (map #(repl-all %1 ys) xs))

user=> (the-quest ["Adam" "Goolan" "silly"] ["a" "oo" "ll"])
("Adm" "Gln" "siy")

There's two slightly different formulations of the problem and your example doesn't quite indicate which you want:

  1. Make one pass, removing any substring of the input strings which matches any of the second strings.
  2. Make one pass for each string to remove in sequence. This can remove more characters than option 1, as each removal can create new substrings which otherwise wouldn't qualify.

If what you want is the second case, that seems to be taken care of. If it's the first case, I'd suggest something like

(import java.util.regex.Pattern)

(defn the-quest [strs to-remove]
  (let[my-pattern (->> to-remove
                       (map #(Pattern/quote %))
                       (clojure.string/join "|")
                       re-pattern)]
    (map #(clojure.string/replace % my-pattern "") strs)))

Here I just create a regular expression matching any of the to-remove strings and do one replace on instances of the regex. You have to bring in Pattern/quote if you want to be able to use regex control characters in the to-removes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM