<p>I have wondered for some time, what a nice, clean solution for joining an array of strings might look like.
Example: I have ["Alpha", "Beta", "Gamma"] and want to join the strings into one, separated by commas – "Alpha, Beta, Gamma".</p>

<p>Now I know that most programming languages offer some kind of join method for this. I just wonder how these might be implemented.
When I took introductory courses, I often tried to go it alone, but never found a satisfactory algorithm. Everything seemed rather messy, the problem being that you can not just loop through the array, concatenating the strings, as you would add one too many commas (either before or after the last string).
I don’t want to check conditions in the loop. I don’t really want to add the first or the last string before/after the loop (I guess this is maybe the best way?).</p>

<p>Can someone show me an elegant solution? Or tell me exactly why there can’t be anything more elegant?</p>

[{'answer_id': 58437, 'author': 'Mendelt', 'author_id': 3320, 'author_profile': 'https://Stackoverflow.com/users/3320', 'pm_score': 4, 'selected': False, 'text': '<p>The most elegant solution i found for problems like this is something like this (in pseudocode)</p>\n\n<pre><code>separator = ""\nforeach(item in stringCollection)\n{\n    concatenatedString += separator + item\n    separator = ","\n}\n</code></pre>\n\n<p>You just run the loop and only after the second time around the separator is set. So the first time it won\'t get added. It\'s not as clean as I\'d like it to be so I\'d still add comments but it\'s better than an if statement or adding the first or last item outside the loop.</p>\n'}, {'answer_id': 58440, 'author': 'Matt Sheppard', 'author_id': 797, 'author_profile': 'https://Stackoverflow.com/users/797', 'pm_score': 2, 'selected': False, 'text': '<p>I usually go with something like...</p>\n\n<pre><code>list = ["Alpha", "Beta", "Gamma"];\noutput = "";\nseparator = "";\nfor (int i = 0; i &lt; list.length ; i++) {\n  output = output + separator;\n  output = output + list[i];\n  separator = ", ";\n}\n</code></pre>\n\n<p>This works because on the first pass, separator is empty (so you don\'t get a comma at the start, but on every subsequent pass, you add a comma before adding the next element.</p>\n\n<p>You could certainly unroll this a little to make it a bit faster (assigning to the separator over and over isn\'t ideal), though I suspect that\'s something the compiler could do for you automatically.</p>\n\n<p>In the end though, I suspect pretty this is what most language level join functions come down to. Nothing more than syntax sugar, but it sure is sweet.</p>\n'}, {'answer_id': 58441, 'author': 'Luke Halliwell', 'author_id': 3974, 'author_profile': 'https://Stackoverflow.com/users/3974', 'pm_score': 2, 'selected': False, 'text': '<p>For pure elegance, a typical recursive functional-language solution is quite nice.  This isn\'t in an actual language syntax but you get the idea (it\'s also hardcoded to use comma separator):</p>\n\n<p>join([]) = ""</p>\n\n<p>join([x]) = "x"</p>\n\n<p>join([x, rest]) = "x," + join(rest)</p>\n\n<p>In reality you would write this in a more generic way, to reuse the same algorithm but abstract away the data type (doesn\'t have to be strings) and the operation (doesn\'t have to be concatenation with a comma in the middle).  Then it usually gets called \'reduce\', and many functional languages have this built in, e.g. multiplying all numbers in a list, in Lisp:</p>\n\n<p>(reduce #\'* \'(1 2 3 4 5)) =>  120</p>\n'}, {'answer_id': 58452, 'author': 'Patrick', 'author_id': 429, 'author_profile': 'https://Stackoverflow.com/users/429', 'pm_score': 3, 'selected': False, 'text': '<p>All of these solutions are decent ones, but for an underlying library, both independence of separator and decent speed are important. Here is a function that fits the requirement assuming the language has some form of string builder.</p>\n\n<pre><code>public static string join(String[] strings, String sep) {\n  if(strings.length == 0) return "";\n  if(strings.length == 1) return strings[0];\n  StringBuilder sb = new StringBuilder();\n  sb.append(strings[0]);\n  for(int i = 1; i &lt; strings.length; i++) {\n    sb.append(sep);\n    sb.append(strings[i]);\n  }\n  return sb.toString();\n}\n</code></pre>\n\n<p>EDIT: I suppose I should mention why this would be speedier. The main reason would be because any time you call c = a + b; the underlying construct is usually c = (new StringBuilder()).append(a).append(b).toString();. By reusing the same string builder object, we can reduce the amount of allocations and garbage we produce. </p>\n\n<p>And before someone chimes in with optimization is evil, we\'re talking about implementing a common library function. Acceptable, scalable performance is one of the requirements them. A join that takes a long time is one that\'s going to be not oft used.</p>\n'}, {'answer_id': 58454, 'author': 'David L Morris', 'author_id': 3137, 'author_profile': 'https://Stackoverflow.com/users/3137', 'pm_score': 1, 'selected': False, 'text': '<p>\' Pseudo code Assume zero based</p>\n\n<pre>\nResultString = InputArray[0]\nn = 1\nwhile n (is less than)  Number_Of_Strings\n    ResultString (concatenate) ", "\n    ResultString (concatenate) InputArray[n]\n    n = n + 1\nloop\n</pre>\n'}, {'answer_id': 58455, 'author': 'Konrad Rudolph', 'author_id': 1968, 'author_profile': 'https://Stackoverflow.com/users/1968', 'pm_score': 0, 'selected': False, 'text': "<p>The following is no longer language-agnostic (but that doesn't matter for the discussion because the implementation is easily portable to other languages). I tried to implement Luke's (theretically best) solution in an imperative programming language. Take your pick; mine's C#. Not very elegant at all. However, (without any testing whatsoever) I could imagine that its performance is quite decent because the recursion is in fact tail recursive.</p>\n\n<p>My challenge: give a better recursive implementation (in an imperative language). You say what “better” means: less code, faster, I'm open for suggestions.</p>\n\n<pre><code>private static StringBuilder RecJoin(IEnumerator&lt;string&gt; xs, string sep, StringBuilder result) {\n    result.Append(xs.Current);\n    if (xs.MoveNext()) {\n        result.Append(sep);\n        return RecJoin(xs, sep, result);\n    } else\n        return result;\n}\n\npublic static string Join(this IEnumerable&lt;string&gt; xs, string separator) {\n    var i = xs.GetEnumerator();\n    if (!i.MoveNext())\n        return string.Empty;\n    else\n        return RecJoin(i, separator, new StringBuilder()).ToString();\n}\n</code></pre>\n"}, {'answer_id': 58496, 'author': 'Jon Ericson', 'author_id': 1438, 'author_profile': 'https://Stackoverflow.com/users/1438', 'pm_score': 1, 'selected': False, 'text': '<p>In Perl, I just use the <strong>join</strong> command:</p>\n\n<pre><code>$ echo "Alpha\nBeta\nGamma" | perl -e \'print(join(", ", map {chomp; $_} &lt;&gt; ))\'\nAlpha, Beta, Gamma\n</code></pre>\n\n<p>(The <strong>map</strong> stuff is mostly there to create a list.)</p>\n\n<p>In languages that don\'t have a built in, like C, I use simple iteration (untested):</p>\n\n<pre><code>for (i = 0; i &lt; N-1; i++){\n    strcat(s, a[i]);\n    strcat(s, ", ");\n}\nstrcat(s, a[N]);\n</code></pre>\n\n<p>Of course, you\'d need to check the size of <em>s</em> before you add more bytes to it.  </p>\n\n<p>You either have to special case the <a href="https://stackoverflow.com/questions/58431/algorithm-for-joining-eg-an-array-of-strings#58454">first entry</a> or the last.</p>\n'}, {'answer_id': 58515, 'author': 'Bobby Jack', 'author_id': 5058, 'author_profile': 'https://Stackoverflow.com/users/5058', 'pm_score': 3, 'selected': False, 'text': '<p>Most languages nowadays - e.g. perl (mention by Jon Ericson), php, javascript - have a join() function or method, and this is by far the most elegant solution. Less code is better code.</p>\n\n<p>In response to Mendelt Siebenga, if you do require a hand-rolled solution, I\'d go with the ternary operator for something like:</p>\n\n<pre><code>separator = ","\nforeach (item in stringCollection)\n{\n    concatenatedString += concatenatedString ? separator + item : item\n}\n</code></pre>\n'}, {'answer_id': 61319, 'author': 'jfs', 'author_id': 4279, 'author_profile': 'https://Stackoverflow.com/users/4279', 'pm_score': 2, 'selected': False, 'text': '<p>@Mendelt Siebenga</p>\n\n<p>Strings are corner-stone objects in programming languages. Different languages implement strings differently. An implementation of <code>join()</code> strongly depends on underlying implementation of strings. Pseudocode doesn\'t reflect underlying implementation.</p>\n\n<p>Consider <code>join()</code> in Python. It can be easily used:</p>\n\n<pre><code>print ", ".join(["Alpha", "Beta", "Gamma"])\n# Alpha, Beta, Gamma\n</code></pre>\n\n<p>It could be easily implemented as follow:</p>\n\n<pre><code>def join(seq, sep=" "):\n    if not seq:         return ""\n    elif len(seq) == 1: return seq[0]\n    return reduce(lambda x, y: x + sep + y, seq)\n\nprint join(["Alpha", "Beta", "Gamma"], ", ")\n# Alpha, Beta, Gamma\n</code></pre>\n\n<p>And here how <code>join()</code> method is implemented in C (taken from <a href="http://svn.python.org/view/python/trunk/Objects/stringobject.c?rev=66119&amp;view=markup" rel="nofollow noreferrer">trunk</a>):</p>\n\n<pre><code>PyDoc_STRVAR(join__doc__,\n"S.join(sequence) -&gt; string\\n\\\n\\n\\\nReturn a string which is the concatenation of the strings in the\\n\\\nsequence.  The separator between elements is S.");\n\nstatic PyObject *\nstring_join(PyStringObject *self, PyObject *orig)\n{\n    char *sep = PyString_AS_STRING(self);\n    const Py_ssize_t seplen = PyString_GET_SIZE(self);\n    PyObject *res = NULL;\n    char *p;\n    Py_ssize_t seqlen = 0;\n    size_t sz = 0;\n    Py_ssize_t i;\n    PyObject *seq, *item;\n\n    seq = PySequence_Fast(orig, "");\n    if (seq == NULL) {\n        return NULL;\n    }\n\n    seqlen = PySequence_Size(seq);\n    if (seqlen == 0) {\n        Py_DECREF(seq);\n        return PyString_FromString("");\n    }\n    if (seqlen == 1) {\n        item = PySequence_Fast_GET_ITEM(seq, 0);\n        if (PyString_CheckExact(item) || PyUnicode_CheckExact(item)) {\n            Py_INCREF(item);\n            Py_DECREF(seq);\n            return item;\n        }\n    }\n\n    /* There are at least two things to join, or else we have a subclass\n     * of the builtin types in the sequence.\n     * Do a pre-pass to figure out the total amount of space we\'ll\n     * need (sz), see whether any argument is absurd, and defer to\n     * the Unicode join if appropriate.\n     */\n    for (i = 0; i &lt; seqlen; i++) {\n        const size_t old_sz = sz;\n        item = PySequence_Fast_GET_ITEM(seq, i);\n        if (!PyString_Check(item)){\n#ifdef Py_USING_UNICODE\n            if (PyUnicode_Check(item)) {\n                /* Defer to Unicode join.\n                 * CAUTION:  There\'s no gurantee that the\n                 * original sequence can be iterated over\n                 * again, so we must pass seq here.\n                 */\n                PyObject *result;\n                result = PyUnicode_Join((PyObject *)self, seq);\n                Py_DECREF(seq);\n                return result;\n            }\n#endif\n            PyErr_Format(PyExc_TypeError,\n                     "sequence item %zd: expected string,"\n                     " %.80s found",\n                     i, Py_TYPE(item)-&gt;tp_name);\n            Py_DECREF(seq);\n            return NULL;\n        }\n        sz += PyString_GET_SIZE(item);\n        if (i != 0)\n            sz += seplen;\n        if (sz &lt; old_sz || sz &gt; PY_SSIZE_T_MAX) {\n            PyErr_SetString(PyExc_OverflowError,\n                "join() result is too long for a Python string");\n            Py_DECREF(seq);\n            return NULL;\n        }\n    }\n\n    /* Allocate result space. */\n    res = PyString_FromStringAndSize((char*)NULL, sz);\n    if (res == NULL) {\n        Py_DECREF(seq);\n        return NULL;\n    }\n\n    /* Catenate everything. */\n    p = PyString_AS_STRING(res);\n    for (i = 0; i &lt; seqlen; ++i) {\n        size_t n;\n        item = PySequence_Fast_GET_ITEM(seq, i);\n        n = PyString_GET_SIZE(item);\n        Py_MEMCPY(p, PyString_AS_STRING(item), n);\n        p += n;\n        if (i &lt; seqlen - 1) {\n            Py_MEMCPY(p, sep, seplen);\n            p += seplen;\n        }\n    }\n\n    Py_DECREF(seq);\n    return res;\n}\n</code></pre>\n\n<hr>\n\n<p>Note that the above <code>Catenate everything.</code> code is a small part of the whole function.</p>\n\n<p>In pseudocode:</p>\n\n<pre><code>/* Catenate everything. */\nfor each item in sequence\n    copy-assign item\n    if not last item\n        copy-assign separator\n</code></pre>\n'}, {'answer_id': 61581, 'author': 'jfs', 'author_id': 4279, 'author_profile': 'https://Stackoverflow.com/users/4279', 'pm_score': 0, 'selected': False, 'text': '<p><code>join()</code> function in Ruby:</p>\n\n<pre><code>def join(seq, sep) \n  seq.inject { |total, item| total &lt;&lt; sep &lt;&lt; item } or "" \nend\n\njoin(["a", "b", "c"], ", ")\n# =&gt; "a, b, c"\n</code></pre>\n'}, {'answer_id': 61623, 'author': 'jfs', 'author_id': 4279, 'author_profile': 'https://Stackoverflow.com/users/4279', 'pm_score': 0, 'selected': False, 'text': "<p><code>join()</code> in Perl: </p>\n\n<pre><code>use List::Util qw(reduce);\n\nsub mjoin($@) {$sep = shift; reduce {$a.$sep.$b} @_ or ''}\n\nsay mjoin(', ', qw(Alpha Beta Gamma));\n# Alpha, Beta, Gamma\n</code></pre>\n\n<p>Or without <code>reduce</code>:</p>\n\n<pre><code> sub mjoin($@) \n {\n   my ($sep, $sum) = (shift, shift); \n   $sum .= $sep.$_ for (@_); \n   $sum or ''\n }\n</code></pre>\n"}, {'answer_id': 64299, 'author': 'Brad Gilbert', 'author_id': 1337, 'author_profile': 'https://Stackoverflow.com/users/1337', 'pm_score': 0, 'selected': False, 'text': '<h2>Perl 6</h2>\n<pre><code>sub join( $separator, @strings ){\n  my $return = shift @strings;\n  for @strings -&gt; ( $string ){\n    $return ~= $separator ~ $string;\n  }\n  return $return;\n}\n</code></pre>\n<p><em>Yes I know it is pointless because Perl 6 already has a join function.</em></p>\n'}, {'answer_id': 76738, 'author': 'Mark B', 'author_id': 13070, 'author_profile': 'https://Stackoverflow.com/users/13070', 'pm_score': 0, 'selected': False, 'text': '<p><strong>In Java 5, with unit test:</strong></p>\n\n<pre><code>import junit.framework.Assert;\nimport org.junit.Test;\n\npublic class StringUtil\n{\n    public static String join(String delim, String... strings)\n    {\n        StringBuilder builder = new StringBuilder();\n\n        if (strings != null)\n        {\n            for (String str : strings)\n            {\n                if (builder.length() &gt; 0)\n                {\n                    builder.append(delim);\n                }\n\n                builder.append(str);\n            }\n        }           \n\n        return builder.toString();\n    }\n\n    @Test\n    public void joinTest()\n    {\n        Assert.assertEquals("", StringUtil.join(", ", null));\n        Assert.assertEquals("", StringUtil.join(", ", ""));\n        Assert.assertEquals("", StringUtil.join(", ", new String[0]));\n        Assert.assertEquals("test", StringUtil.join(", ", "test"));\n        Assert.assertEquals("foo, bar", StringUtil.join(", ", "foo", "bar"));\n        Assert.assertEquals("foo, bar, baz", StringUtil.join(", ", "foo", "bar", "baz"));\n    }\n}\n</code></pre>\n'}, {'answer_id': 80475, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': '<p>I wrote a recursive version of the solution in lisp. If the length of the list is greater that 2 it splits the list in half as best as it can and then tries merging the sublists</p>\n\n<pre><code>    (defun concatenate-string(list)\n       (cond ((= (length list) 1) (car list))\n             ((= (length list) 2) (concatenate \'string (first list) "," (second list)))\n             (t (let ((mid-point (floor (/ (- (length list) 1) 2))))\n                   (concatenate \'string \n                                (concatenate-string (subseq list 0 mid-point))\n                                ","\n                                (concatenate-string (subseq list mid-point (length list))))))))\n\n\n\n    (concatenate-string \'("a" "b"))\n</code></pre>\n\n<p>I tried applying the divide and conquer strategy to the problem, but I guess that does not give a better result than plain iteration. Please let me know if this could have been done better. </p>\n\n<p>I have also performed an analysis of the recursion obtained by the algorithm, it is available <a href="http://www4.ncsu.edu/~rfcornel/analysis.pdf" rel="nofollow noreferrer">here</a>. </p>\n'}, {'answer_id': 437254, 'author': 'blabla999', 'author_id': 48469, 'author_profile': 'https://Stackoverflow.com/users/48469', 'pm_score': 1, 'selected': False, 'text': '<p>collecting different language implementations ?\n<br>Here is, for your amusement, a Smalltalk version:</p>\n\n<pre><code>join:collectionOfStrings separatedBy:sep\n\n  |buffer|\n\n  buffer := WriteStream on:\'\'.\n  collectionOfStrings \n      do:[:each | buffer nextPutAll:each ]\n      separatedBy:[ buffer nextPutAll:sep ].\n  ^ buffer contents.\n</code></pre>\n\n<p>Of course, the above code is already in the standard library found as:</p>\n\n<p>Collection >> asStringWith:</p>\n\n<p>so, using that, you\'d write:</p>\n\n<pre><code>#(\'A\' \'B\' \'C\') asStringWith:\',\'\n</code></pre>\n\n<p><strong>But here\'s my main point</strong>:</p>\n\n<p>I would like to put more emphasis on the fact that using a StringBuilder (or what is called "WriteStream" in Smalltalk) is highly recommended. Do not concatenate strings using "+" in  a loop - the result will be many many intermediate throw-away strings. If you have a good Garbage Collector, thats fine. But some are not and a lot of memory needs to be reclaimed. StringBuilder (and WriteStream, which is its grand-grand-father) use a buffer-doubling or even adaptive growing algorithm, which needs <em>MUCH</em> less scratch memory. </p>\n\n<p>However, if its only a few small strings you are concatenating, dont care, and "+" them; the extra work using a StringBuilder might be actually counter-productive, up to an implementation- and language-dependent number of strings.</p>\n'}, {'answer_id': 719348, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 0, 'selected': False, 'text': '<p>Use the String.join method in C#</p>\n\n<p><a href="http://msdn.microsoft.com/en-us/library/57a79xd0.aspx" rel="nofollow noreferrer">http://msdn.microsoft.com/en-us/library/57a79xd0.aspx</a></p>\n'}]
['https://Stackoverflow.com/questions/58431', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/4991/']