Reputation: 4151
Given the following code snip:
using (var reader = cmd.ExecuteReader())
{
while(reader.Read())
{
var count = reader.FieldCount; // the first column must be name all subsequent columns are treated as data
var data = new List<double>();
for (var i = 1; i < count; i++)
{
data.Add(Convert.ToDouble(reader[i].ToString()));
}
barChartSeries.Add(new ColumnBarChart.ColumnChartSeries((string)reader[0],
data));
columnChart.xAxis.categories.Add((string)reader[0]);
}
}
Is there an easy way to eliminate the for loop? Perhaps using linq?
reader[0] will always be a string reader[0+?] will be a double
I want to pull all the doubles into a list if possible.
Upvotes: 1
Views: 1279
Reputation: 5672
You could use the LINQ Cast method to get something you can use other LINQ methods on, but I agree with the other posters - there's nothing wrong with a for loop. LINQ methods will just use a less efficient loop in the background.
I believe this should work, but haven't set up a data set to test it.
reader.Cast<Double>().Skip(1).ToList();
Upvotes: 0
Reputation: 1500055
Speed is somewhat of a concern I suppose.
Then you're focusing on entirely the wrong problem.
Out of the things you're doing here, looping is the least inefficient part. More worrying is that you're converting from a double
to string
and then back to double
. At least fix your code to:
for (var i = 1; i < count; i++)
{
data.Add(reader.GetDouble(i));
}
You could create the list with the known size, too:
List<double> data = new List<double>(count - 1);
Even then, I strongly suspect that's going to be irrelevant compared with the serialization and database access.
Whatever you do, something is going to be looping. You could go to great lengths to hide the looping (e.g. by writing an extension method to iterate over all the values in a row) - but really, I don't see that there's anything wrong with it here.
I strongly advise you to avoid micro-optimizing until you've proven there's a problem. I'd be utterly astonished if this bit of code you're worrying about is a bottleneck at all. Generally, you should write the simplest code which achieves what you want it to, decide on your performance criteria and then test against them. Only move away from simple code when you need to.
Upvotes: 6
Reputation: 43596
The only way I can see to remove the forloop
is to use Enumerable.Range
.
But anyway you could do something like:
var data = new List<double>(Enumerable.Range(1, count).Select(i => reader.GetDouble(i)));
But I see no benefit to this approch, and it just makes the code unreadable
Upvotes: 2
Reputation:
I dont think you can loop on it because
public class SqlDataReader : DbDataReader, IDataReader, IDisposable, IDataRecord
and this class does not implement IEnumerable
Upvotes: 0