Yanıtlar:
Sadece rastgele bir listeye katılmak istiyorsanız:
"StringA" <> " " <> "StringB"
veya yalnızca dize enterpolasyonunu kullanın:
"#{a} #{b}"
Liste boyutunuz keyfi ise:
Enum.join(["StringA", "StringB"], " ")
... yukarıdaki tüm çözümler geri dönecek
"StringA StringB"
Sahip olduğunuz rastgele bir listeyse, kullanabilirsiniz Enum.join
, ancak yalnızca iki veya üç içinse, açık dize birleştirmenin okunması daha kolay olmalıdır
"StringA" <> " " <> "StringB"
Bununla birlikte, örneğin ağ üzerinden çıkış yapacaksanız, genellikle bellekte tek bir dize olması gerekmez. Bu durumda, verileri kopyalamaktan koruyan bir iolist (belirli bir derin liste türü) kullanmak avantajlı olabilir. Örneğin,
iex(1)> IO.puts(["StringA", " ", "StringB"])
StringA StringB
:ok
Bu dizeleri bir yerde değişken olarak alacağınız için, derin bir liste kullanarak, başka bir yerde çıktı almak için tamamen yeni bir dize ayırmaktan kaçınırsınız. İksir / erlang'daki birçok fonksiyon iolistleri anlar, bu yüzden ekstra iş yapmanıza gerek kalmaz.
Bir Enum.reduce örnek numaranız için de işe yarar mı?
iex(4)> Enum.reduce(["StringA", "StringB"], fn(x, acc) -> x <> " " <> acc end)
"StringB StringA"
Ne yapmaya çalıştığınıza bağlıdır. Sadece yeni bir değişkene yazmaya çalışıyorsanız, aşağıdakilerden birini kullanın:
Dize enterpolasyonu
a = "StringA"
b = "StringB"
"#{a} #{b}"
Dize birleştirme: "StringA" <> " " <> "StringB
Enum.join()
: ["StringA", "StringB"] |> Enum.join(" ")
Bununla birlikte, Uri'nin belirttiği gibi, IOListler de kullanılabilir:
["StringA", " ", "StringB"] |> IO.iodata_to_binary
Kaynak tüketimini önemsemeniz gerekiyorsa aslında IOListler en yüksek performans göstereceklerdir. Big Nerd Ranch, IOLists ile performans kazançları hakkında iyi bir yazıya sahiptir.
Birkaç yöntem vardır, ancak nil değerlerini nasıl işlediğini bilmek hangi yöntemi seçmeniz gerektiğini belirleyebilir.
Bu bir hata verecektir
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)
Bu sadece boş bir "" dizesi ekleyecektir:
iex(1)> "my name is #{nil}"
"my name is "
Bu şekilde:
iex(3)> Enum.join(["my name is", nil], " ")
"my name is "
Ayrıca türleri de göz önünde bulundurun. İle <>
size herhangi bir serbest casting alamadım:
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"
Uygulamadaki performans aşağı yukarı aynı görünüyor:
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}
Bu nedenle, enterpolasyonlu değerler nil
veya yanlış tip olduğunda çökmek isteyip istemediğinize gerçekten bağlıdır .
Bir IO Listesi kullanmayı düşünün, eğer ["String1", "string2"] varsa ve üzerinde iolist_to_binary / 1 kullanıyorsanız, bu dizeleri yeni bir dizeye kopyalayacaksınız. Bir ES listeniz varsa, çoğu durumda listenin çıktısını alabilirsiniz ve bu bağlantı noktasını bağlantı noktasında birleştirir. Ve bu anahtar şeydir, çalışma zamanının verilerin kopyalarını alması gerekmez, böylece birleştirme işleminden çok daha verimlidir.
["StringA", "StringB"] |> Enum.join " "