अमृत ​​में तार कैसे जुड़ेंगे?


158

मैं एक स्थान के साथ सूची में दो तार कैसे शामिल करूं, जैसे:

["StringA", "StringB"]

हो जाता है

"StringA StringB"

जवाबों:


220

यदि आप बस कुछ मनमानी सूची में शामिल होना चाहते हैं:

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

या बस स्ट्रिंग प्रक्षेप का उपयोग करें:

 "#{a} #{b}"

यदि आपकी सूची का आकार मनमाना है:

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

... उपरोक्त सभी समाधान वापस आ जाएंगे

"StringA StringB"

36
पाइपलाइन ऑपरेटर का उपयोग करके वैकल्पिक वाक्यविन्यास: ["StringA", "StringB"] |> Enum.join " "
रयान क्रॉमवेल

11
जब आपको वास्तव में पाइप संचालन की आवश्यकता नहीं होती है तो आपको पाइपलाइन ऑपरेटर से बचना चाहिए।
कार्लोस

3
@EdMelo देखभाल पर विस्तार से क्यों? तकनीकी रूप से आपको पाइप संचालन के लिए वास्तव में कभी भी "आवश्यकता" नहीं होती है, क्योंकि एक ही व्यवहार नेस्टिंग फ़ंक्शन कॉल द्वारा प्राप्त किया जा सकता है।
Schrockwell

8
@Schrockwell हाँ, "चाहिए" बहुत ज्यादा था। मेरा मतलब है कि इस मामले में आपको पठनीयता में कोई लाभ नहीं है, इसलिए एक सादे फ़ंक्शन कॉल से विचार अधिक स्पष्ट हो जाएंगे।
कार्लोस

3
संभावित नियोक्ताओं को प्रदर्शित करने के लिए आपको एलिक्सिर भाषा का उतना ही उपयोग करना चाहिए जितना कि आप जानते हैं। तो मैं एक ही फ़ाइल में उपरोक्त सभी समाधानों का उपयोग करूंगा।
rodmclaughlin

61

यदि आपके पास एक मनमानी सूची है, तो आप उपयोग कर सकते हैं Enum.join, लेकिन अगर यह सिर्फ दो या तीन के लिए है, तो स्पष्ट स्ट्रिंग संघनन को पढ़ना आसान होना चाहिए

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

हालाँकि, अक्सर आपको इसे मेमोरी में सिंगल स्ट्रिंग के रूप में रखने की आवश्यकता नहीं होती है यदि आप इसे उदाहरण के लिए नेटवर्क के माध्यम से आउटपुट करने जा रहे हैं। उस मामले में, एक आईओलिस्ट (एक विशिष्ट प्रकार की गहरी सूची) का उपयोग करना फायदेमंद हो सकता है, जो आपको डेटा की प्रतिलिपि बनाने से बचाता है। उदाहरण के लिए,

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

चूँकि आपके पास वे तार कहीं चर के रूप में होंगे, एक गहरी सूची का उपयोग करके, आप इसे कहीं और आउटपुट करने के लिए एक नया स्ट्रिंग आवंटित करने से बचते हैं। अमृत ​​/ एरांग में कई कार्य आईओलिस्ट को समझते हैं, इसलिए आपको अक्सर अतिरिक्त काम करने की आवश्यकता नहीं होगी।


यदि आप एक पाइप कमांड "स्ट्रिंग" के अंत में कुछ जोड़ने के लिए की जरूरत है |।> (& (& 1 <> "\ n")) ()
hwatkins

9

पूर्णता के लिए उत्तर देते हुए, आप स्ट्रिंग इंटरपोल का उपयोग भी कर सकते हैं :

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

5

यदि आप अपनी सूची में स्थान जोड़ने के साथ ठीक थे, तो आप इसे आईओलिस्ट के रूप में मान सकते हैं:

["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 "
आंद्रेई सूरा

व्यक्तिगत रूप से लगता है कि यह सबसे अच्छा जवाब है क्योंकि यह अन्य मामलों के लिए सामान्यीकरण करता है जहां कम उपयोग किया जा सकता है। आर। में "do.call" के विचार से बात करता है
थॉमस ब्राउन ने

3

यह इस बात पर निर्भर करता है कि आप क्या करने की कोशिश कर रहे हैं। यदि आप एक नए चर को लिखने का प्रयास कर रहे हैं, तो बस या तो उपयोग करें:

  • स्ट्रिंग इंटरपोलेशन

    a = "StringA"
    b = "StringB"
    "#{a} #{b}"
    
  • स्ट्रिंग संघनन: "StringA" <> " " <> "StringB

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

हालांकि, जैसा कि उरी ने उल्लेख किया है, IOLists का भी उपयोग किया जा सकता है:

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

IOLists वास्तव में सबसे अधिक प्रदर्शन करने वाले हैं यदि आपको संसाधन खपत के बारे में ध्यान रखने की आवश्यकता है। बिग नर्ड रेंच का प्रदर्शन लाभ w / IOLists पर एक अच्छा लेखन है


2

कई तरीके हैं, लेकिन यह जानना कि यह कैसे शून्य मानों को संभालता है, यह निर्धारित कर सकता है कि आपको किस विधि का चयन करना चाहिए।

यह एक त्रुटि फेंक देगा

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

एक IO सूची का उपयोग करने पर विचार करें, यदि आपके पास ["String1", "string2"] है और आप उस पर iolist_to_binary / 1 का उपयोग करते हैं तो आप उन स्ट्रिंग को एक नए स्ट्रिंग में कॉपी करेंगे। यदि आपके पास एक IO सूची है, तो आप इसे ज्यादातर मामलों में आउटपुट कर सकते हैं और यह इसे पोर्ट पर उपलब्ध कराएगा। और यह एक महत्वपूर्ण बात है, रनटाइम को डेटा की प्रतियां बनाने की आवश्यकता नहीं होगी, इसलिए यह समवर्ती की तुलना में बहुत अधिक कुशल है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.