c# - C# GetRange 包装
问题描述
我想问一下是否有与 List.GetRange(id,count) 类似的方法但已包装。它接受超过索引的正负起始 id 和计数。当超出集合时,元素会从头开始获取吗?
我想到的唯一方法是:
List<T> e = new List<T>{a,b,c,d,e,f};
int start=4%e.Count;
int n= 5;
List<T> eNew = new List<T>(n);
for (int i=start; i<start+n i++)
eNew.Add(e[i%e.Count]);
是否有任何现有的类似内置命令可以执行此操作或更快?
解决方案
我不相信有这样的方法。当然,必须小心确保这样的功能预期会以这种方式运行。如果编码人员认为如果超出范围会得到错误,反而会得到结果,那将是不好的。
但是为了您自己的方便,您可以自己创建一个通用的扩展方法。我在下面做了一个。除了将循环的代码之外,此代码将允许从负索引开始。甚至除此之外,它将允许负长度。
public static class MyExtensions {
public static List<T> GetRingedRange<T> (
this List<T> list,
int start,
int n
) {
Func<decimal,decimal,int> trueModulo = (a,b) => {
if (a >= 0)
return (int)(a % b);
var roundsToPositive = Math.Ceiling(Math.Abs(Convert.ToDecimal(a) / b));
a += Convert.ToInt32(roundsToPositive * b);
return (int)(a % b);
};
start = trueModulo(start, list.Count);
start=start%list.Count;
List<T> range = new List<T>();
for (
int i=start;
n > 0 ? i < start + n : i > start + n; // i < or > start + n?
i += n > 0 ? 1 : -1 // step forwards or backwards?
) {
range.Add(list[trueModulo(i,list.Count)]);
}
return range;
}
}
所以你可以这样做:
List<char> e = new List<char>{'a','b','c','d','e','f'};
var newRange = e.GetRingedRange(4,5); // e, f, a, b, c
newRange = e.GetRingedRange(-4,5); // c, d, e, f, a
newRange = e.GetRingedRange(4,-7); // e, d, c, b, a, f, e
推荐阅读
- python - 加速 Pandas DataFrame 过滤器
- firebase - 谷歌(gmail登录)在颤动
- arrays - 重用 uint8_t 缓冲区来存储 UART 响应
- malloc - 为什么 malloced 字符串不适用于 strcat?
- linux - 使用 gdb 在特定行设置断点
- html - 如何仅在创建后将规则应用于子元素(CSS)?
- reactjs - 即使使用 setState 并且状态已更改,Recharts Brush 的“startIndex”也不会更改
- php - paypal api 使用php确定产品的价格
- javascript - 以文件名为标题的多文件上传
- html - 如何使用可调整大小的页眉、页脚和侧边栏制作这个基于 CSS 网格的圣杯布局?