Hoe voeg je snaren samen in Elixir?

Hoe voeg ik twee strings in een lijst samen met een spatie, zoals:

["StringA", "StringB"]

wordt

"StringA StringB"

Antwoord 1, autoriteit 100%

Als je gewoon op een willekeurige lijst wilt staan:

"StringA" <> " " <> "StringB"

of gebruik gewoon string-interpolatie:

"#{a} #{b}"

Als de grootte van uw lijst willekeurig is:

Enum.join(["StringA", "StringB"], " ")

… alle bovenstaande oplossingen zullen terugkeren

"StringA StringB"

Antwoord 2, autoriteit 26%

Als je een willekeurige lijst hebt, kun je Enum.joingebruiken, maar als het voor slechts twee of drie is, zou expliciete tekenreeksaaneenschakeling gemakkelijker te lezen moeten zijn

"StringA" <> " " <> "StringB"

Vaak hoeft u het echter niet als een enkele tekenreeks in het geheugen te hebben als u het wilt uitvoeren via b.v. het netwerk. In dat geval kan het voordelig zijn om een ​​iolist (een specifiek type van een deep list) te gebruiken, waardoor u geen gegevens hoeft te kopiëren. Bijvoorbeeld,

iex(1)> IO.puts(["StringA", " ", "StringB"])
StringA StringB
:ok

Omdat je die strings ergens als variabelen zou hebben, door een diepe lijst te gebruiken, vermijd je het toewijzen van een hele nieuwe string om het ergens anders uit te voeren. Veel functies in elixer/erlang begrijpen iolisten, dus u hoeft vaak niet het extra werk te doen.


Antwoord 3, autoriteit 4%

Voor de volledigheid kunt u ook String-interpolatiegebruiken:

iex(1)> [a, b] = ["StringA", "StringB"]
iex(2)> "#{a} #{b}"
"StringA StringB"

Antwoord 4, autoriteit 3%

Er zijn een aantal methoden, maar als u weet hoe het omgaat met nulwaarden, kunt u bepalen welke methode u moet kiezen.

Dit geeft een foutmelding

iex(4)> "my name is " <> "adam"
"my name is adam"
iex(1)> "my name is " <> nil
** (ArgumentError) expected binary argument in <> operator but got: nil
    (elixir) lib/kernel.ex:1767: Kernel.wrap_concatenation/3
    (elixir) lib/kernel.ex:1758: Kernel.extract_concatenations/2
    (elixir) lib/kernel.ex:1754: Kernel.extract_concatenations/2
    (elixir) expanding macro: Kernel.<>/2
    iex:1: (file)

Hiermee wordt alleen een lege tekenreeks “” ingevoegd:

iex(1)> "my name is #{nil}"
"my name is "

En dit:

iex(3)> Enum.join(["my name is", nil], " ")
"my name is "

Houd ook rekening met typen. Met <>krijg je geen gratis casting:

iex(5)> "my name is " <> 1
** (ArgumentError) expected binary argument in <> operator but got: 1
    (elixir) lib/kernel.ex:1767: Kernel.wrap_concatenation/3
    (elixir) lib/kernel.ex:1758: Kernel.extract_concatenations/2
    (elixir) lib/kernel.ex:1754: Kernel.extract_concatenations/2
    (elixir) expanding macro: Kernel.<>/2
    iex:5: (file)
iex(5)> "my name is #{1}"
"my name is 1"
iex(7)> Enum.join(["my name is", 1], " ")
"my name is 1"

Prestaties in de praktijk lijken ongeveer hetzelfde:

iex(22)> :timer.tc(fn -> Enum.each(1..10_000_000, fn _ -> "my name is " <> "adam" end) end)
{8023855, :ok}
iex(23)> :timer.tc(fn -> Enum.each(1..10_000_000, fn _ -> "my name is " <> "adam" end) end)
{8528052, :ok}
iex(24)> :timer.tc(fn -> Enum.each(1..10_000_000, fn _ -> "my name is " <> "adam" end) end)
{7778532, :ok}
iex(25)> :timer.tc(fn -> Enum.each(1..10_000_000, fn _ -> "my name is #{"adam"}" end) end)
{7620582, :ok}
iex(26)> :timer.tc(fn -> Enum.each(1..10_000_000, fn _ -> "my name is #{"adam"}" end) end)
{7782710, :ok}
iex(27)> :timer.tc(fn -> Enum.each(1..10_000_000, fn _ -> "my name is #{"adam"}" end) end)
{7743727, :ok}

Dus, hangt er echt van af of je wilt crashen of niet wanneer de geïnterpoleerde waarden nilof het verkeerde type zijn.


5, Autoriteit 2%

een ENUM.Reduce zou ook werken voor uw voorbeeld NO?

iex(4)> Enum.reduce(["StringA", "StringB"], fn(x, acc) -> x <> " " <> acc end)
"StringB StringA"


6

Overweeg een IO-lijst te gebruiken, als u [“String1”, “String2”] hebt en u IOLIST_TO_BINIËLE / 1 op deze gebruikt, kopieert u die snaren in een nieuwe reeks. Als u een IO-lijst hebt, kunt u het in de meeste gevallen gewoon uitvoeren en het zal het in de haven aaneenbrengen. En dit is het belangrijkste ding, de runtime hoeven geen kopieën van de gegevens te maken, zodat het veel efficiënter is dan aaneenschakeling.

Other episodes