Is there a extended FirstBetween method for C# List<T>

本文关键字:List gt lt for there extended FirstBetween method Is | 更新日期: 2023-09-27 18:24:33

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

例如,我有一个int列表[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;
    }
}

这是未完成的代码,我觉得这太复杂了,作为一个模板方法,它仍然存在一些其他问题。

有更简单的方法吗?

Is there a extended FirstBetween method for C# List<T>

对泛型类型使用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;
    }
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;
        }
    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;
    }