C# equivalent of Python’s list slicing (list[:])
A useful extension method.
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: /// <summary>Slices the specified collection like Python does</summary> 2: /// <typeparam name="T"></typeparam> 3: /// <param name="me">the collection</param> 4: /// <param name="start">The start point.</param> 5: /// <param name="end">The end point.</param> 6: /// <returns></returns> 7: /// <exception cref="System.ArgumentException">starting point must be less than or equal to ending point;start</exception> 8: /// <example> 9: /// <code> 10: /// var numbers=new[]{1,2,3,4,5}; 11: /// var eg = numbers.Slice(-3,-1); 12: /// foreach (var i in eg) 13: /// { 14: /// Console.Write("{0}, ", i); 15: /// } 16: /// Console.Writeline(); 17: /// 18: /// // Output: 3, 4, 19: /// </code> 20: /// </example> 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: }