50

It's probably something silly I missed, but I try to concatenate a list of integers instead of summing them with:

integerArray.Aggregate((accumulator, piece) => accumulator+"," + piece)

The compiler complained about argument error. Is there a slick way to do this without having to go through a loop?

Haoest
  • 13,610
  • 29
  • 89
  • 105

4 Answers4

82

Which version of .NET? In 4.0 you can use:

string.Join(",", integerArray);

In 3.5 I would be tempted to just use:

string.Join(",", Array.ConvertAll(integerArray, i => i.ToString()));

assuming it is an array. Otherwise, either make it an array, or use StringBuilder.

sashoalm
  • 75,001
  • 122
  • 434
  • 781
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • would it not always be best perf wise to use a StringBuilder in this case? – Damien McGivern May 26 '10 at 23:46
  • 5
    Oddly enough, the Join is more performant that the StringBuilder. I did a test, and with an array 1,000,000 in size, Join took 207ms, while StringBuilder took 264ms. I suspect this is because the Join is optimized for the task, whereas the SB is optimized more for the general case. – Cyberherbalist May 27 '10 at 00:28
  • If I didn't have an `Array` type to begin with, is there a speed difference between `Array.ConvertAll(list.ToArray(),...)` versus `IEnumerable.Select(...).ToArray()`? – Michael Mar 21 '12 at 21:05
  • 2
    @Michael the key difference is that it might need some intermediate arrays and block-copies while it finds the length. But in most cases, you'll be fine. – Marc Gravell Mar 21 '12 at 21:16
  • The StringBuilder will probably speed up considerably if you created it with a large enough initial capacity. – dviljoen Nov 05 '13 at 14:46
26

You probably want to use String.Join.

string.Join(",", integerArray.Select(i => i.ToString()).ToArray());

If you're using .Net 4.0, you don't need to go through the hassle of reifying an array. and can just do

 string.Join(",", integerArray);
48klocs
  • 6,073
  • 3
  • 27
  • 34
21

The error you are getting is because you didn't use the override of Aggregate which lets you specify the seed. If you don't specify the seed, it uses the type of the collection.

integerArray.Aggregate("", (accumulator, piece) => accumulator + "," + piece);
Samuel
  • 37,778
  • 11
  • 85
  • 87
  • 1
    +1 because you answered the question. However, your code has O(n^2) performance. Not cool. – Kennet Belenky May 26 '10 at 23:39
  • 1
    @KennetBelenky, `Aggregate` is nothing but a foreach loop that sets the value of a variable. - That's O(n) not O(n^2)? – ebb Aug 03 '14 at 11:32
  • 1
    @ebb The runtime of 'accumulator + ...' is proportional to the length of the value in accumulator. The length of the accumulator string grows with each invocation. The code is performing an O(n) operation, n times. That's how it's O(n^2). – Kennet Belenky Aug 13 '14 at 20:57
  • 1
    because seed is "", this would return a string with the first value a comma , e.g. ,1,2,3,4 . A solution would be to return `integerArray.First() + integerArray.Skip(1).Aggregate("", (accumulator, piece) => accumulator + "," + piece);` – Razvan Jul 12 '18 at 19:36
  • the more simpler way to get rid of the extra prepended comma is ::: integerArray.Aggregate( "",(x, y) => string.Concat(x,",", y)).Substring(1) – OmGanesh May 09 '19 at 00:16
5

Just to add another alternative to @Marc's

var list = string.Join( ",", integerArray.Select( i => i.ToString() ).ToArray() );
tvanfosson
  • 524,688
  • 99
  • 697
  • 795