66

I have a DataTable that returns

IDs
,1
,2
,3
,4
,5
,100
,101

I want to convert this to single string value, i.e:

,1,2,3,4,5,100,101

How can i rewrite the following to get a single string

var _values = _tbl.AsEnumerable().Select(x => x);
StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
user160677
  • 4,233
  • 12
  • 42
  • 55
  • 2
    It is unclear - what data is returened? Do you have DataRows, and a column of ID? Also, there is confusion over the commas - is it possible they exist in the data base and are already present, or should you add them? – Kobi Aug 05 '10 at 12:13
  • Thank you to all kind hearted – user160677 Aug 05 '10 at 12:13
  • 5
    `Select(x => x);` makes absolutely no sense, especially in your case – abatishchev Aug 05 '10 at 12:15
  • Check this out http://msdn.microsoft.com/en-us/library/a8ycds2f%28VS.80%29.aspx – sjjoshi Aug 05 '10 at 11:42
  • 1
    Does this answer your question? [How to convert IEnumerable to one comma separated string?](https://stackoverflow.com/questions/7481964/how-to-convert-ienumerablestring-to-one-comma-separated-string) – StayOnTarget Mar 19 '21 at 13:53

7 Answers7

160
var singleString = string.Join(",", _values.ToArray() );
Winston Smith
  • 21,585
  • 10
  • 60
  • 75
  • 1
    Do you need to call ToArray() on _values? – Alex Humphrey Aug 05 '10 at 11:45
  • 3
    Simplest solution, I was about to answer that but you'll need to add .ToArray() on _values. – Julien N Aug 05 '10 at 11:46
  • @ck It depends on exactly what the input data are. Just replace `","` by `String.Empty` if the commas are already in the data. – Julien N Aug 05 '10 at 11:53
  • @Julien N - I'm just returning the favour, except my answer produces the right result... – cjk Aug 05 '10 at 11:55
  • 3
    @ck I guess it's a matter of interpretation. I read the commas as peculiar to the OP's formatting rather than being part of the data. In any case, `string.Join` is probably the simplest method of achieving the desired result. – Winston Smith Aug 05 '10 at 12:00
  • 28
    On .Net 4 `Join` and `Concat` take `IEnumerable`, and you don't need `ToArray`. So, it depends. – Kobi Aug 05 '10 at 12:08
12

Write an extension method such as

public static String AppendAll(this IEnumerable<String> collection, String seperator)
{
    using (var enumerator = collection.GetEnumerator())
    {
        if (!enumerator.MoveNext())
        {
            return String.Empty;
        }

        var builder = new StringBuilder().Append(enumerator.Current);

        while (enumerator.MoveNext())
        {
            builder.Append(seperator).Append(enumerator.Current);
        }

        return builder.ToString();
    }
}

and assuming the result of your previous expression is IEnumerable<String>, call:

var _values = _tbl.AsEnumerable().Select(x => x).AppendAll(String.Empty);    
Alex Humphrey
  • 6,099
  • 4
  • 26
  • 41
  • Apologies for the extras in that extension method - it's one I use quite often to join strings together which suits this case. – Alex Humphrey Aug 05 '10 at 11:53
  • 1
    And why the downvote - I know there's extra stuff in there that may not be needed for the question, but it works. – Alex Humphrey Aug 05 '10 at 12:00
  • @Alex - the framework has string.Join, which you might find useful. See http://msdn.microsoft.com/en-us/library/57a79xd0.aspx – Winston Smith Aug 05 '10 at 12:01
  • 3
    @Winston: I'm aware of String.Join. I would of course use it if the source of the data was an array. String.Join requires an array, which has to be held entirely in memory. The array is then copied to the String, again in memory. The memory requirements for String.Join are therefore more than what I have written, which iterates through the items in a sequence one by one and appends them to a string. String.Join is another way which involves a memory requirements/complexity tradeoff. – Alex Humphrey Aug 05 '10 at 12:07
  • 2
    Alex - your are a bit outdated on that one: http://msdn.microsoft.com/en-us/library/dd992421.aspx . Also, it is too early to think about performances, certainly without profiling. What if the data in question is very small, or already in an array? – Kobi Aug 05 '10 at 12:16
  • @Kobi - thanks, that's good to know - we're still on .NET 3.5 here. – Alex Humphrey Aug 05 '10 at 12:18
  • 1
    @Kobi - I was simply discussing the potential tradeoffs, and why my approach was still a valid one. I guess the fact that String.Join takes an enumerable in .NET 4.0 proves that smarter people than me agree. – Alex Humphrey Aug 05 '10 at 12:24
5
 String.Join(
      ",",
      _tbl.AsEnumerable()
          .Select(r => r.Field<int>("ID").ToString())
          .ToArray())
abatishchev
  • 98,240
  • 88
  • 296
  • 433
4

Try this:

var _values = _tbl.AsEnumerable().Select(x => x);
string valueString = _values.ToList().Aggregate((a, b) => a + b);
Tim S. Van Haren
  • 8,861
  • 2
  • 30
  • 34
  • You forgot the separator. a + separator + b – Adrian Godong Aug 05 '10 at 11:44
  • 2
    There is no separator required by the OP – cjk Aug 05 '10 at 11:46
  • 3
    +1 but why the two steps and call to `ToList`? Why not just `_tbl.AsEnumerable().Select(x => x).Aggregate((a, b) => a + b);`? – Kent Boogaart Aug 05 '10 at 11:56
  • In theory, correct. In fact - a number of mistakes. `Select(x => x)` makes not sense because `AsEnumerable()` already makes table `IEnumerable` not `List` – abatishchev Aug 05 '10 at 12:09
  • I got the result when i execute _tbl.AsEnumerable().Select(x => x.Field(columnName)).Aggregate((a, b) => a + b) (I am working on Typed DataSet) – user160677 Aug 05 '10 at 12:13
  • @csharpbaby: `Aggregate((a, b) => a + b)` in your case will do the same as `Sum()` - sum all numbers together. However in your original post you said that you need a string, separated by comma. So `String.Join(",", array)` is what you need – abatishchev Aug 05 '10 at 12:37
  • And `a + b` with a & b being strings is absolutely not processor / memory performant (`"+"` creates a new string for each iteration) – Julien N Aug 05 '10 at 12:48
3

I had a similar issue with general Array type and i solved it as follows

string GetMembersAsString(Array array)
{
    return string.Join(",", array.OfType<object>());
}

Note that call OfType<object>() is mandatory.

honzakuzel1989
  • 2,400
  • 2
  • 29
  • 32
2

You can use MoreLINQ extension

var singleString = _values.ToDelimitedString(",");
Ad23
  • 106
  • 1
  • 7
0

You can cheat with this:

String output = "";
_tbl.AsEnumerable().Select(x => output += x).ToArray(); 
// output now contains concatenated string

Note ToArray() or similar is needed to force the query to execute.

Another option is

String output = String.Concat(_tbl.AsEnumerable().Select(x=>x).ToArray());
cjk
  • 45,739
  • 9
  • 81
  • 112
  • @Winston - There is no separator required, reread the question. – cjk Aug 05 '10 at 11:50
  • Second option : `String output = String.Concat(_tbl.AsEnumerable().ToArray());` would do the same, no ? (without the `Select`) – Julien N Aug 05 '10 at 12:05