Search code examples
stringreplacehy

hylang replace multiple words


I would like to perform multiple replace operations on a string, in hylang

Given that hy is very similar to python i found a related solution on Python replace multiple strings

# python
def replace(s, repls):
   reduce(lambda a, kv: a.replace(*kv), repls, s)
replace("hello, world", [["hello", "goodbye"],["world", "earth"]])
> 'goodbye, earth'

so i tried to port it to hy:

;hy
(defn replace [s repls]
    (reduce (fn [a kv] (.replace a kv)) repls s))
(replace "hello, world", [["hello" "bye"] ["earth" "moon"]])
> TypeError: replace() takes at least 2 arguments (1 given)

this fails, as the kv argument to the lambda-function in reduce is interpreted as single arg (e.g. ["hello" "bye"]) instead of two args "hello" & "bye".

In python i can use the *-operator to dereference the list to arguments, but it seems i cannot do that in hy.

(defn replace [s repls]
    (reduce (fn [a kv] (.replace a *kv)) repls s))
> NameError: global name '*kv' is not defined

Is there an elegant way to

  • expand lists as arguments
  • AND/OR to replace multiple words in a string

in hy?


Solution

  • the trick seems to be to use (apply)

    (defn replace-words
          [s repls]
          (reduce (fn [a kv] (apply a.replace kv)) repls s))
    (replace-words "hello, world" (, (, "hello" "goodbye") (, "world" "blue sky")))