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;
}
}
这是未完成的代码,我觉得这太复杂了,作为一个模板方法,它仍然存在一些其他问题。
有更简单的方法吗?
对泛型类型使用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;
}