سؤال

I have a generic GetMinimum method. It accepts array of IComparable type (so it may be string[] or double[]). in the case of double[] how can I implement this method to ignore the double.NaN values? (I'm looking for good practices)

when I pass this array

double[] inputArray = { double.NaN, double.NegativeInfinity, -2.3, 3 };

it returns the double.NaN!

public T GetMinimum<T>(T[] array) where T : IComparable<T>
{
    T result = array[0];
    foreach (T item in array)
    {
        if (result.CompareTo(item) > 0)
        {
            result = item;
        }
    }
    return result;
}
هل كانت مفيدة؟

المحلول

Since both NaN < x and NaN > x will always be false, asking for the minimum of a collection that can contain NaN is simply not defined. It is like dividing by zero: there is no valid answer.

So the logical approach would be to pre-filter the values. That will not be generic but that should be OK.

 var results = inputArray.EliminateNaN().GetMinimum();

Separation of concerns: the filtering should not be the responsibility (and burden) of GetMinimum().

نصائح أخرى

You can't from inside the method. The reason is you have no idea what T can be from inside the method. May be you can by some little casting, but ideally this should be your approach:

public T GetMinimum<T>(T[] array, params T[] ignorables) where T : IComparable<T>
{
    T result = array[0]; //some issue with the logic here.. what if array is empty
    foreach (T item in array)
    {
        if (ignorables.Contains(item)
            continue;

        if (result.CompareTo(item) > 0)
        {
            result = item;
        }
    }
    return result;
}

Now call this:

double[] inputArray = { double.NaN, double.NegativeInfinity, -2.3, 3 };
GetMinimum(inputArray, double.NaN);

If you're sure there is only item to be ignored, then you can take just T as the second parameter (perhaps as an optional parameter).

Or otherwise in a shorter approach, just:

inputArray.Where(x => !x.Equals(double.NaN)).Min();

According to this Q&A, it's complicated: Sorting an array of Doubles with NaN in it

Fortunately, you can hack around it:

if( item is Single || item is Double ) {
    Double fitem = (Double)item;
    if( fitem == Double.NaN ) continue;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top