views:

137

answers:

6

Hi. 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);
A: 

Try this:

var _values = _tbl.AsEnumerable().Select(x => x);
string valueString = _values.ToList().Aggregate((a, b) => a + b);
Tim S. Van Haren
You forgot the separator. a + separator + b
Adrian Godong
There is no separator required by the OP
ck
+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
In theory, correct. In fact - a number of mistakes. `Select(x => x)` makes not sense because `AsEnumerable()` already makes table `IEnumerable<DataRow`. `ToList()` makes no sense, `Aggregate()` is a member if `IEnumerable<T>` not `List<T>`
abatishchev
I got the result when i execute _tbl.AsEnumerable().Select(x => x.Field<string>(columnName)).Aggregate((a, b) => a + b) (I am working on Typed DataSet)
@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
Julien N
+1  A: 

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
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
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
@Alex - the framework has string.Join, which you might find useful. See http://msdn.microsoft.com/en-us/library/57a79xd0.aspx
Winston Smith
@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
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
@Kobi - thanks, that's good to know - we're still on .NET 3.5 here.
Alex Humphrey
@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
+6  A: 
var singleString = string.Join(",", _values.ToArray() );
Winston Smith
Do you need to call ToArray() on _values?
Alex Humphrey
Simplest solution, I was about to answer that but you'll need to add .ToArray() on _values.
Julien N
Indeed. Answer updated.
Winston Smith
@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
@Julien N - I'm just returning the favour, except my answer produces the right result...
ck
@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
Comments removed.
ck
On .Net 4 `Join` and `Concat` take `IEnumerable`, and you don't need `ToArray`. So, it depends.
Kobi
A: 

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());
ck
@Winston - There is no separator required, reread the question.
ck
Second option : `String output = String.Concat(_tbl.AsEnumerable().ToArray());` would do the same, no ? (without the `Select`)
Julien N
A: 
 String.Join(
      ",",
      _tbl.AsEnumerable()
          .Select(r => r.Field<int>("ID").ToString())
          .ToArray())
abatishchev