ฉันจะรวมสองสายในรายการด้วยช่องว่างได้อย่างไรเช่น:
["StringA", "StringB"]
กลายเป็น
"StringA StringB"
ฉันจะรวมสองสายในรายการด้วยช่องว่างได้อย่างไรเช่น:
["StringA", "StringB"]
กลายเป็น
"StringA StringB"
คำตอบ:
หากคุณเพียงแค่ต้องการเข้าร่วมรายการโดยพลการ:
"StringA" <> " " <> "StringB"
หรือเพียงแค่ใช้การแก้ไขสตริง:
"#{a} #{b}"
ถ้าขนาดของรายการของคุณโดยพลการ:
Enum.join(["StringA", "StringB"], " ")
... คำตอบทั้งหมดข้างต้นจะกลับมา
"StringA StringB"
หากสิ่งที่คุณมีคือรายการที่กำหนดเองคุณสามารถใช้Enum.join
แต่ถ้าเป็นเพียงสองหรือสามรายการการต่อสตริงที่ชัดเจนควรอ่านง่ายขึ้น
"StringA" <> " " <> "StringB"
อย่างไรก็ตามบ่อยครั้งที่คุณไม่จำเป็นต้องใช้มันเป็นสายอักขระเดียวในหน่วยความจำหากคุณกำลังจะเอาท์พุทผ่านเช่นเครือข่าย ในกรณีนี้การใช้ไอโอลิสต์ (รายการเฉพาะแบบลึก) มีประโยชน์สำหรับการทำสำเนาซึ่งช่วยให้คุณประหยัดจากการคัดลอกข้อมูล ตัวอย่างเช่น,
iex(1)> IO.puts(["StringA", " ", "StringB"])
StringA StringB
:ok
เนื่องจากคุณจะต้องมีสตริงเหล่านั้นเป็นตัวแปรอยู่ที่ไหนสักแห่งโดยใช้รายการลึกคุณหลีกเลี่ยงการจัดสรรสตริงใหม่ทั้งหมดเพียงเพื่อส่งออกที่อื่น ฟังก์ชั่นมากมายในยาอายุวัฒนะ / erlang เข้าใจไอโอลิสต์ดังนั้นคุณมักจะไม่จำเป็นต้องทำงานพิเศษ
ตอบรับเพื่อความสมบูรณ์คุณยังสามารถใช้การแก้ไขสตริง :
iex(1)> [a, b] = ["StringA", "StringB"]
iex(2)> "#{a} #{b}"
"StringA StringB"
หากคุณตกลงกับการเพิ่มช่องว่างในรายการของคุณคุณสามารถถือว่าเป็น iolist:
["StringA", " ", "StringB"] |> IO.iodata_to_binary # "StringA StringB"
สิ่งนี้จะช่วยเพิ่มการแสดงบางอย่างเนื่องจากคุณไม่ได้ทำซ้ำสตริงใด ๆ ในหน่วยความจำ
Enum.reduce จะทำงานด้วยสำหรับตัวอย่างของคุณไม่?
iex(4)> Enum.reduce(["StringA", "StringB"], fn(x, acc) -> x <> " " <> acc end)
"StringB StringA"
มันขึ้นอยู่กับสิ่งที่คุณกำลังพยายามที่จะทำ หากคุณเพียงแค่พยายามเขียนตัวแปรใหม่ให้ใช้อย่างใดอย่างหนึ่ง:
การแก้ไขสตริง
a = "StringA"
b = "StringB"
"#{a} #{b}"
การเรียงสตริง: "StringA" <> " " <> "StringB
Enum.join()
: ["StringA", "StringB"] |> Enum.join(" ")
อย่างไรก็ตามดังที่ Uri ได้กล่าวไว้ IOLists ยังสามารถนำมาใช้:
["StringA", " ", "StringB"] |> IO.iodata_to_binary
IOLists จริง ๆ แล้วจะเป็นคนที่มีประสิทธิภาพมากที่สุดถ้าคุณต้องการดูแลเกี่ยวกับการใช้ทรัพยากร Big Nerd Ranch มีการเขียนเพิ่มประสิทธิภาพที่ดีขึ้นพร้อมกับ IOLists
มีหลายวิธี แต่การรู้วิธีจัดการกับค่าศูนย์สามารถกำหนดวิธีการที่คุณควรเลือก
นี่จะทำให้เกิดข้อผิดพลาด
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)
นี่จะเป็นการแทรกสตริงว่าง "":
iex(1)> "my name is #{nil}"
"my name is "
ตามนี้:
iex(3)> Enum.join(["my name is", nil], " ")
"my name is "
พิจารณาประเภทด้วย เมื่อ<>
คุณไม่ได้รับการคัดเลือกนักแสดงฟรี:
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"
ประสิทธิภาพในทางปฏิบัติดูเหมือนกันโดยประมาณ:
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}
ดังนั้นขึ้นอยู่กับว่าคุณต้องการที่จะพังหรือไม่เมื่อค่าสอดแทรกnil
หรือประเภทผิด
พิจารณาใช้รายการ IO หากคุณมี ["String1", "string2"] และคุณใช้ iolist_to_binary / 1 ในนั้นคุณจะคัดลอกสตริงเหล่านั้นลงในสตริงใหม่ หากคุณมีรายการ IO คุณสามารถเอาท์พุทมันในกรณีส่วนใหญ่และมันจะเรียงต่อกันบนพอร์ต และนี่คือกุญแจสำคัญรันไทม์ไม่จำเป็นต้องทำสำเนาข้อมูลดังนั้นมันจึงมีประสิทธิภาพมากกว่าการต่อข้อมูล
["StringA", "StringB"] |> Enum.join " "