65.9K
CodeProject is changing. Read more.
Home

C# equivalent of Python’s list slicing (list[:])

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.67/5 (4 votes)

Oct 3, 2013

CPOL
viewsIcon

11232

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: }