简体   繁体   中英

C# Lambda for assigning DataTable rows to array

All,

I've read the previous answers to this question and can't find anything that addresses my specific question. I am trying to get all the values in a column into an array. This is what I have, and it works, but I am trying to learn lambdas:

pointCount = myDataTable.Rows.Count;
xData = new double[pointCount];
yData = new double[pointCount];

for (int i = 0; i < pointCount; i++)
{                
   xData[i] = (double)myDataTable.Rows[i]["XData"];
   yData[i] = (double)myDataTable.Rows[i]["YData"];
}

For the life of me i can't figure out the lambda syntax needed to eliminate the loop.

Thanks for your help, -Bill

You can use Select to get the same result like following which is lambda expression based:

var result = myDataTable.Rows.AsEnumerable()
             .Select(x=> new 
                      { 
                          XData = x.Field<double>("XData"),
                          YData = x.Field<double>("YData")
                       }).ToArray();

But this would give you a single anonymous object having two properties in it XData and YData as one array of objects.

You can also have them in separate arrays like you have in your question but it would be a overkill as we would have to iterate all the collection two times then like:

xData = myDataTable.Rows.AsEnumerable()
             .Select(x=>  x.Field<double>("XData")).ToArray();

yData = myDataTable.Rows.AsEnumerable()
             .Select(x=> x.Field<double>("YData")).ToArray();

Try this:

xData = myDataTable.AsEnumerable().Select(x => x.Field<double>("XData")).ToArray();

yData = myDataTable.AsEnumberable().Select(x => x.Field<double>("YDate")).ToArray();

You use AsEnumerable() from System.Data.Extensions to make the datatable object an enumerable then the Select query grabs each row from datatable, then x.Field specifies the column type (double) and the parenthesis after with the string value specifies the column name, then to finish it off you call ToArray() to convert the linq collection to an array. Hope this helps.

I don't particularly like the answer as the person below me is trying to show you that you could do this all in one select, but as the comments point out his answer is flawed due to it being anonymous objects. To make this better, consider making a custom class with two properties for x and y, then make an array for custom class, then do your linq Select and place the values into each property for each object in array.

You won't be able to do it as-is. The rows are an instance of DataRowCollection , which inherits InternalDataCollectionBase . Neither type is obviously IEnumerable .

InternalDataCollectionBase may implement IEnumerable , but if it does, it'll require a cast. Then you should be able to write a LINQ query like this:

((IEnumerable)myDataTable.Rows).ForEach(r => 
{
    xData[i] = (double)r["XData"];
    yData[i] = (double)r["YData"];
}

Again, this depends on whether or not InternalDataCollectionBase provides an explicit implementation of IEnumerable .

I can't recall off the top of my head whether or not ForEach is a valid LINQ extension. If it isn't, here it is:

public static void ForEach<T>(this IEnumerable<T> sequence,
                              Action<T> action)
{
    foreach(T item in sequence)
    {
        action(item);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM