엘릭서에서 문자열을 결합하는 방법?


158

공백이있는 목록에서 두 문자열을 결합하는 방법은 다음과 같습니다.

["StringA", "StringB"]

된다

"StringA StringB"

답변:


220

임의의 목록에 가입하려는 경우 :

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

또는 문자열 보간을 사용하십시오.

 "#{a} #{b}"

목록 크기가 임의 인 경우 :

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

... 위의 모든 솔루션이 반환됩니다

"StringA StringB"

36
파이프 라인 연산자를 사용하는 대체 구문 : ["StringA", "StringB"] |> Enum.join " "
Ryan Cromwell

11
실제로 파이프 작업을 수행 할 필요가없는 경우 파이프 라인 연산자를 사용하지 않아야합니다.
Carlos

3
@EdMelo 왜 신경 써야합니까? 기술적으로는 파이프 함수에 "필요"하지 않습니다. 중첩 함수 호출로 동일한 동작을 수행 할 수 있기 때문입니다.
Schrockwell

8
@ Schrockwell 그래, "해야한다"너무 많아. 의미하는 것은이 경우 가독성이 없으므로 일반 함수 호출로 생각을보다 명확하게 할 수 있습니다.
Carlos

3
잠재적 고용주에게 자신이 아는 것을 증명하기 위해 가능한 한 많은 Elixir 언어를 사용해야합니다. 따라서 위의 모든 솔루션을 동일한 파일에서 사용합니다.
rodmclaughlin 2016 년

61

가지고있는 것이 임의의 목록이라면을 사용할 수 Enum.join있지만 2 ~ 3 인 경우 명시 적 문자열 연결을 쉽게 읽을 수 있어야합니다

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

그러나 네트워크 등을 통해 출력하려는 ​​경우 종종 메모리에서 단일 문자열로 가질 필요가 없습니다. 이 경우, 데이터 복사에서 절약되는 iolist (특정 유형의 딥 목록)를 사용하는 것이 유리할 수 있습니다. 예를 들어

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

딥 목록을 사용하여 해당 문자열을 변수로 사용할 수 있으므로 다른 곳에서 출력하기 위해 완전히 새로운 문자열을 할당하지 마십시오. elixir / erlang의 많은 함수는 iolist를 이해하므로 추가 작업을 수행 할 필요가없는 경우가 많습니다.


파이프 명령 끝에 "String"|> (& (& 1 <> "\ n"))을 추가해야 할 경우. ()
hwatkins

9

완성도에 대한 응답으로 문자열 보간 을 사용할 수도 있습니다 .

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

5

목록에 공백을 추가해도 괜찮다면이를 iolist로 취급 할 수 있습니다.

["StringA", " ", "StringB"] |> IO.iodata_to_binary # "StringA StringB"

메모리의 문자열을 복제하지 않으므로 성능이 약간 향상됩니다.


4

Enum.reduce도 귀하의 예에 맞지 않습니까?

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


예, 그러나 역 Enum.reduce ([ "a", "b", "c"] |> Enum.reverse, fn (x, acc)-> x <> ""<> acc end) "ab가 필요합니다. c "
Andrei Sura

개인적으로 이것이 최선의 대답이라고 생각합니다. 그것이 그것이 사용될 수있는 다른 경우로 일반화되기 때문입니다. R.의 "do.call"아이디어에 대해 이야기
Thomas Browne

3

당신이하려는 일에 달려 있습니다. 새 변수에 쓰려고하면 다음 중 하나를 사용하십시오.

  • 문자열 보간

    a = "StringA"
    b = "StringB"
    "#{a} #{b}"
    
  • 문자열 연결 : "StringA" <> " " <> "StringB

  • Enum.join(): ["StringA", "StringB"] |> Enum.join(" ")

그러나 Uri가 언급했듯이 IOList를 사용할 수도 있습니다.

["StringA", " ", "StringB"] |> IO.iodata_to_binary

리소스 소비에 관심이 있다면 IOList는 실제로 가장 성능이 우수합니다. Big Nerd Ranch는 IOList를 통한 성능 향상에 대해 잘 작성 했습니다.


2

여러 가지 방법이 있지만 nil 값을 처리하는 방법을 알면 선택해야 할 방법을 결정할 수 있습니다.

오류가 발생합니다

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잘못되었거나 유형이 잘못된 경우 충돌 여부를 결정 합니다.


0

당신은 또한 할 수 있습니다 'string A' ++ ' ' ++ 'string B'


7
그들은 문자 목록이되지 않습니까?
Virtual

0

IO 목록 사용을 고려하십시오. [ "String1", "string2"]가 있고 iolist_to_binary / 1을 사용하면 해당 문자열을 새 문자열로 복사합니다. IO 목록이 있으면 대부분의 경우 출력 할 수 있으며 포트에서 연결됩니다. 이것이 핵심입니다. 런타임은 데이터 복사본을 만들 필요가 없으므로 연결보다 훨씬 효율적입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.