-3

特定のデータが次のデータよりも大きく、次のデータよりも小さい最初の位置 (インデックスを位置として扱うことができます) を見つけるジェネリック メソッドが必要です。

たとえば、int list[12,34,4,65] があり、数値 15 (12 より大きく 34 より小さい) を指定すると 1 が返され、数値 50 を指定すると 3 が返されます。など

これは私が書いたものですが、もっと簡単な方法があるに違いないと思います:

public static class ExtensionMethods
{
    public static int FirstBetween<T>(this List<T> list, T t)
    {
        if (list == null)
            return -1;
        if(t == null)
            return -1;
        if(list.Count == 0 )
            return 0;

        T item1;
        for(int index = 0;index<list.Count;index++)
        {
            T item2 = list[index];
            if(IsBetween(item1,item2,t))
                return index;

            item1 = item2;            
        }          
        return list.Count;  
    }

    private static bool IsBetween<T>(T t1, T t2, T t)
    {
        if (t1 == null && t2 == null)
            return false;
        else if(t1==null && t<=t2)//in case of the first item
            return true;
        else if (t2 == null && t >= t1)//in case of the last item
            return true;
        else if(t>=t1 && t<=t2)
            return true;
        else
            return false;
    }
}

これは未完成のコードで、複雑すぎると感じます。また、テンプレート メソッドとしては、まだいくつかの問題があります。

これを行う簡単な方法はありますか?

4

3 に答える 3

3

ジェネリック型に IComparable 制約を使用すると、うまくいくはずです。

  public static int FirstBetween<T>( this List<T> list, T value) where T:IComparable<T> {
        if (list == null || value == null) return -1;

        for (int index = 1; index < list.Count; index++) {
            if (( list[index - 1].CompareTo( value ) < 0 ) 
                  && list[index].CompareTo( value ) > 0)
                return index;
        }
        return list.Count;
    }

最適化されたバージョンですが、読みにくく、リスト内の null 項目をまだチェックしていないため、少し見苦しくなります:

    public static int FirstBetween<T>( this List<T> list, T value) where T:IComparable<T> {
        if (list == null && value == null) return -1;
        if (list.Count == 0) return 0;
        var last = value.CompareTo( list[0] );
        for (int index = 1; index < list.Count; index++) {
            if (( last > 0 ) &&  (last = value.CompareTo(list[index] )) < 0)
                return index;
        }
        return list.Count;
    }
于 2013-07-22T18:09:29.770 に答える
0
    public static int? FirstBetween<T>(this List<T> list, T val) where T : IComparable
    {
        if (list != null && !ReferenceEquals(val, null))
        {
            bool greater = false;
            for (int i = 1; i < list.Count; i++)
            {
                var lastGreater = i == 1 ? (list[i-1].CompareTo(val) > 0) : greater;
                greater = list[i].CompareTo(val) > 0;
                if (!lastGreater && greater)
                    return i;
            }
        }
        return null;
    }
于 2013-07-22T18:19:55.050 に答える