Thanks for the proposal!

I assume those languages do not have a powerful mechanism for traversing
binaries like Elixir does though?

In Elixir you could do:

    for <<char <- input>>, do: maybe_replace(char), into: ""

Note we are matching in characters though, so:

    defp maybe_replace(?A), do: "a"
    ...
    defp maybe_replace(char), do: <<char>>

You can also use pattern matching and recursion.

Both variants should be quite more efficient than an API that expects a map
and do map look-ups. It also gives you more control over what you are
matching (is it characters? Unicode codepoints? 16-bits integers?).

But if for some reason you need map look-ups:

    map = %{
      ?A => "a"
    }
    for <<char <- input>>, do: Map.get(map, char) || <<char>>, into: ""

And finally, if you want to match on substrings (requires Elixir v1.9):

    map = %{
      "AA" => "a"
    }
    String.replace(input, Map.keys(map), &map[&1])

TL;DR - I believe we have more performant and more flexible ways of
achieving the same feature to not warrant the particular "tr"
implementation found in other languages.

*José Valim*
www.plataformatec.com.br
Skype: jv.ptec
Founder and Director of R&D


On Fri, Jun 28, 2019 at 10:44 AM <[email protected]> wrote:

> Recently I found myself wanting to replace certain characters in a string
> with others (similar to "tr" shell command).
>
> In my case I wanted to replace any of the characters in :;<=>?@[\]^_`
> with the corresponding character from ABCDEFGabcdef.
>
> I'm not sure what the most idiomatic way to write this would be in Elixir
> but I used:
>
> Enum.map_join(input, &my_replace/1)
>
> defp my_replace(":"), do: "A"
> defp my_replace(";"), do: "B"
> defp my_replace("<"), do: "C"
> defp my_replace("="), do: "D"
> defp my_replace(">"), do: "E"
> defp my_replace("?"), do: "F"
> defp my_replace("@"), do: "G"
> defp my_replace("["), do: "a"
> defp my_replace("\\"), do: "b"
> defp my_replace("]"), do: "c"
> defp my_replace("^"), do: "d"
> defp my_replace("_"), do: "e"
> defp my_replace("`"), do: "f"
> defp my_replace(char), do: char
>
> This works, is readable, but not concise. My proposal would thus be to
> open a discussion on the way to implement a more concise way to do this,
> unless there is already a concise way to do this that I'm not aware of and
> if people agree that it's worth implementing.
>
> This has been partly discussed before in
> https://github.com/elixir-lang/elixir/issues/4473
>
> Here are some reference implementations in other languages, to open up
> ideas:
>
> PHP:
>
> strtr($input, ":;<=>?@[\]^_`", "ABCDEFGabcdef")
>
> Ruby:
>
> input.tr!(':;<=>?@[\\]^_`', 'ABCDEFGabcdef')
>
> Go has an implementation that is not concise but does allow multiple
> char/string translation:
>
> r := strings.NewReplacer(
>      ":", "A",
>      ";", "B",
>      "<", "C",
>      // and so on...
> )
> r.Replace(input)
>
> Python (3) requires creation of a "translation map" first:
>
> table = str.maketrans(":;<=>?@[\]^_`", "ABCDEFGabcdef")
> input.translate(table)
>
> A lot of these implementations also allow other uses, besides simple
> character translations.
>
> --
> You received this message because you are subscribed to the Google Groups
> "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/elixir-lang-core/LiSFMq0--3-1%40tuta.io
> <https://groups.google.com/d/msgid/elixir-lang-core/LiSFMq0--3-1%40tuta.io?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4KRVAHch2c%2B%3D9h3XishJTHUprfLUFCp-FE-98go1oUuqg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to