Wednesday, December 04, 2013

Slicing .NET - NSlice, the Python like Slice for .Net

Works on my machine - Slicing for .NET

...

First odd thing I read about Python was that a developer can use negative array indices. My reaction was: Why would I even want to get an IndexOutOfRangeException? That is just silly. But then I read what they actually do. They are just like the normal ones. The only difference is that they index the array backwards, for example: -1 means last, -2 means one before last, and so on. That is really handy. I cannot remember how many times I wrote count-1 or count-i.

After that I discovered that Python has an even cooler feature called array slicing. It is something like a quick for loop version. Let me show you an example:

array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print array[1:9:2]

The above code prints [1,3,5,7].

So formally speaking slicing has the following form (each argument can be negative, all arguments are optional):

[ start_index : exclusive_boundary : iteration_step ]

...

This is a really powerful though succinct syntax. Look at the following two examples:

array[::-1] #reverses the array array[1:-1] #skips first and last element

Then I stared to think about those features - how can I port them to C# ?

NSlice

I decided to give it a try and created a .NET library. At the moment there are 3 extension methods:

- Slice – performs slice on a passed collection.
- At - works like an ElementAt extension. The only difference is that the index argument passed to an At extension can be negative.
- AtOrDefault - works like an ElementAtOrDefault extension, but it also accepts negative indices.

But there is more into it. NSlice was written to allow slicing 3 types of .NET collections in the most efficient manner:

- Indexed collections (IList<> implementations) - slicing is performed eagerly and instantly. It does not matter whether the collection has 10 elements or 10 million elements. This is because the result is not created by copying elements, but by creating a transparent view over source collection.
- Enumerables (IEnumerable<> implementations) - slicing is performed lazily. Each possible slice scenario was implemented separately to achieve the best speed performance and least memory footprint. It fits nicely into the LINQ model and could be even used to slice a stream, if the latter was wrapped into IEnumerable<> implementation.
- Strings - slicing is performed eagerly and a new string is returned as a result.

nabuk / NSlice

About NSlice

NSlice is a free .NET library, designed to give you more flexibility in manipulating collections, originally inspired by Python slicing feature.

(Jump straight to the Cheat Sheet if you want to see code samples right away.)

Overview

NSlice was written to allow slicing 3 types of .NET collections in the most efficient manner:

  • Indexed collections (IList<> implementations) - slicing is performed eagerly and instantly. It does not matter whether the collection has 10 elements or 10 million elements. This is because the result is not created by copying elements, but by creating a transparent view over source collection.
  • Enumerables (IEnumerable<> implementations) - slicing is performed lazily. Each possible slice scenario was implemented separately to achieve the best speed performance and least memory footprint.
    It fits nicely into the LINQ model and could be even used to slice a stream, if the latter was wrapped into IEnumerable<> implementation.
  • Strings - slicing is performed eagerly and a new string is returned as a result.

What is slicing ?

Slicing is just a for loop shortcut. Look at the following example:

...

But there is more. Slice allows each argument to be negative. It might seem weird to use negative indices but they are really useful. What are negative indices? They just index the collection backwards, for example: -1 means last, -2 means one before last and so on. See the following two examples to grasp the idea:

  • Get last five elements: Slice(-5)

  • Get collection without first and last element: Slice(1, -1)

...

nabuk / NSlice - Cheat Sheet

This page contains short code snippets that demonstrate NSlice features. If not specified explicitly, examples assume that collection variable has previously been initialized like this:

image

Like the author, the thought of a negative index seems really weird, but after reading about NSlice, it kind of makes sense. And it's much cooler than a reverse for loop. Then there's the other features too...Oh and that he's released the source. Cool, cool and double cool...

No comments: