-3

我想要一种通用方法来找到给定数据大于下一个且小于下一个的第一个位置(我们可以将索引视为位置)。

例如,我有一个 int list[12,34,4,65],如果我给出一个数字 15(大于 12 并且小于 34)它应该返回 1,如果我给出一个数字 50 它应该返回 3 , ETC。

这是我写的,但我觉得必须有一个更简单的方法:

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;
    }

优化版本但可读性较差,仍然不检查列表中的空项,是什么让事情变得有点难看:

    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
private int? returnIndex(int val = 15)
        {
            List<int> myList = new List<int>() { 12, 34, 4, 65 };
            int listCount = myList.Count;
            int? position = null;
            for (int i = 0; i < listCount; i++)
            {
                var currPosition = myList[i];
                if (i + 1 >= listCount)
                {
                    position = i;
                    break;
                }
                var nextPosition = myList[i + 1];
                if (val >= currPosition && val <= nextPosition)
                {
                   position = i +1;
                   break;
                 }
            }
            return position;
        }
于 2013-07-22T17:58:57.677 回答
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 回答