While porting some Python code, I wanted to make it as close of a match as possible so I came up with this extension method.
Enjoy.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: public static IEnumerable<T> Slice<T>(this IEnumerable<T> me, int? start = null, int? end = null)
22: {
23: if (start.HasValue && end.HasValue && start.Value > end.Value)
24: {
25: throw new ArgumentException("starting point must be less than or equal to ending point", "start");
26: }
27:
28: if (start.HasValue && start < 0)
29: {
30: start = me.Count() + start;
31: }
32: if (end.HasValue && end < 0)
33: {
34: end = me.Count() + end;
35: }
36:
37: if (!start.HasValue)
38: {
39: start = 0;
40: }
41:
42: if (!end.HasValue)
43: {
44: end = me.Count();
45: }
46:
47: return me.Skip(start.Value).Take(end.Value - start.Value);
48: }
MSTest:
1: [TestMethod]
2: public void TestSlicing()
3: {
4: var numbers = new[] { 0, 1, 2, 3, 4, 5, 6, 7 };
5: var sliced = numbers.Slice(-3, -1);
6: Assert.AreEqual(2, sliced.Count());
7: Assert.AreEqual(5, sliced.ElementAt(0));
8: Assert.AreEqual(6, sliced.ElementAt(1));
9:
10: sliced = numbers.Slice(1, 4);
11: Assert.AreEqual(3, sliced.Count());
12: Assert.AreEqual(1, sliced.ElementAt(0));
13: Assert.AreEqual(2, sliced.ElementAt(1));
14: Assert.AreEqual(3, sliced.ElementAt(2));
15: }