1

Hi I have a linq query as below

var perChange = (from data in globalDS.Tables[0].AsEnumerable().AsParallel()
              select data.Field<double>("PercentChange")).ToList();

Now the dataset globalDS contains null as well as varchar values in them. So there is an obvious type cast error that is generated. Is there a way to try.Parse the value in "Percentage Change" column and select only the valid fields.

2
  • Why do you have non-numeric data in a PercentChange column? Commented Nov 9, 2012 at 14:38
  • @DStanley The dataset is read from an excel which contains values like NaN as well as null values Commented Nov 9, 2012 at 20:23

3 Answers 3

4

DataRow.Field supports nullable types:

List<double> result = globalDS.Tables[0].AsEnumerable().AsParallel()
             .Where(r  => r.Field<double?>("PercentChange").HasValue)
             .Select(r => r.Field<double?>("PercentChange").Value)
             .ToList();

Edit: Since you have mentioned that the field contains strings instead of doubles:

List<double> result = globalDS.Tables[0].AsEnumerable().AsParallel()
             .Select(r => r.Field<string>("PercentChange").TryGetDouble())
             .Where(nullDouble => nullDouble.HasValue)
             .Select(nullDouble => nullDouble.Value)
             .ToList();

I've used this extension to try-parse a string to double? which is safer than parsing "on the fly" into the local variable, especially with AsParallel:

public static Double? TryGetDouble(this string item, IFormatProvider formatProvider = null)
{
    if (formatProvider == null) formatProvider = NumberFormatInfo.CurrentInfo;
    Double d = 0d;
    bool success = Double.TryParse(item, NumberStyles.Any, formatProvider, out d);
    if (success)
        return d;
    else
        return null;
}
Sign up to request clarification or add additional context in comments.

2 Comments

The OP says that the colun contains varchar values... Wouldn't that mean that r.field<double?> could fail with an InvalidCastException?
Your 2nd code wont work with the .AsParallel() the OP used, the value of d will get unpredictable. If someone coming here needs to work with .AsParallel() look at @DStanley's answer
2

How about this:

double temp;

var perChange = (
     from data in globalDS.Tables[0].AsEnumerable().AsParallel()
     where !data.IsNull("PercentChange")
         && double.TryParse(data.Field<string>("PercentChange"), out temp)
     select double.Parse(data.Field<string>("PercentChange"))
    ).ToList();

Comments

0

Try a select using a where clause in which you check the type. This would be something like: where x != null && TypeOf(x) == double

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.