1

C# Ranges and Indexes

 2 years ago
source link: https://dev.to/andreisfedotov/c-ranges-and-indexes-1nig
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Cover image for C# Ranges and Indexes

C# Ranges and Indexes

Jun 22

・4 min read

Intro

In this tutorial, we're going to go through two new .NET types - System.Index, System.Range and cover appropriate operators: ^ and ...

If you are interested in learning more about C# language, this is for you.

You’ll be able to use the skills and lessons in this tutorial in the real dev world when you work on any project using C#.

It will provide you with a more elegant way to work with sequences and laconic syntax to access elements. Long story short - to use modern language constructions to write easily readable and understandable code.

Ranges and Indexes were introduced as part of .NET Standard 2.1. This is C# 8 feature. It is available in .NET 5, netcore 3.0. It is not supported by .NET Framework. It can be applied for arrays, spans, and readonly spans.

Preparations

First, go to your favorite IDE, it might be Visual Studio, VS Code, Rider, LINQPad, etc. Make sure to start with nothing open or running (except your computer!) I prefer Visual Studio

Next, create a new project and go through the steps.

Steps

The dataset I’m going to use for this tutorial is just a string array of languages.

Create a collection. Let's create an array with the languages.

var languages = new string[] { "Spanish", "English", "Japanese", "French", "German", "Russian", "Italian", "Korean", "Chinese" };
Enter fullscreen modeExit fullscreen mode
Index

How can we get the second element - "English"? It is pretty easy to do, we just have to pass the index (remember that the numeration if indexes in collections in C# starts from 0)

int index = 1;
var english = languages[index];
Console.WriteLine(english); // Output: English
Enter fullscreen modeExit fullscreen mode

Instead of int variable we can use Index type for doing the same:

Index index1 = 1;
var english2 = languages[index1];
Console.WriteLine(english2);
Enter fullscreen modeExit fullscreen mode

Here is another way to create index. Index is value type so when we do new Index() it will set the default value to 0

var index2 = new Index(); // zero by default because this is a structure
var spanish = languages[index2];
Console.WriteLine(spanish);
Enter fullscreen modeExit fullscreen mode

We can pass the index value as a parameter to the constructor

var index3 = new Index(2);
var japanese = languages[index3];
Console.WriteLine(japanese);
Enter fullscreen modeExit fullscreen mode

Probably for now you might ask what is the benefit to use index rather than just integer variable? Okay, probably for accessing the first or second elements there are no many benefits. But in the next examples, we will see getting the last element and will see much more benefits when we will try indexes with ranges together.

The second question here is how can we get the last element? Okay, we can simply get the length of the array and subtract 1. (because of the first element has the index 0 that's way the last element has the index last element - 1)

var lastIndex1 = languages.Length - 1;
var chinese1 = languages[lastIndex1];
Console.WriteLine(chinese1);
Enter fullscreen modeExit fullscreen mode

And the same by using Index:

Index lastIndex2 = ^1;
var chinese2 = languages[lastIndex2];
Console.WriteLine(chinese2);
Enter fullscreen modeExit fullscreen mode

We can do both above examples in one line.

Console.WriteLine(languages[languages.Length - 2]); // Korean
Enter fullscreen modeExit fullscreen mode
Console.WriteLine(languages[^2]); // Korean
Enter fullscreen modeExit fullscreen mode

The struct Index has overwritten method Equals so we can check the equality of the two indexes.

var equals = index1.Equals(index2);
Console.WriteLine(equals); // false
Enter fullscreen modeExit fullscreen mode
Range

Usually, users are forced to implement complex structures to filter/operate on slices of memory or resort to LINQ methods like list.Skip(5).Take(2). With the addition of System.Span<T> and other similar types, it becomes more important to have this kind of operation supported on a deeper level in the language/runtime and have the interface unified.

Range operator .. is a binary infix operator that accepts two expressions, or both expressions can be omitted.

Range myRange1 = 1..4;
Enter fullscreen modeExit fullscreen mode

This can be used with indexes together:

Index start = 1;
Index end = 4;
Range myRange2 = start..end;
Enter fullscreen modeExit fullscreen mode

The following will output the 1, 2 and 3 elements from array:

string[] languagesRange = languages[1..4];
foreach (var language in languagesRange)
{
    Console.WriteLine(language);
}
Enter fullscreen modeExit fullscreen mode

A bit more interesting usages.

3 last elements:

string[] languagesRange1 = languages[^3..];
Enter fullscreen modeExit fullscreen mode

From start to pre-last element (every except the last one)

string[] languagesRange2 = languages[..^1];
Enter fullscreen modeExit fullscreen mode

3 elements before pre-last element

string[] languagesRange3 = languages[^4..^1];
Enter fullscreen modeExit fullscreen mode

As I mentioned earlier the same we can do with Span

Span<string> languagesSpan = languages;
Span<string> selectedLanguagesSpan = languagesSpan[1..4];
foreach (var language in selectedLanguagesSpan)
{
    Console.WriteLine(language);
}
Enter fullscreen modeExit fullscreen mode

Thank you

Thank you very much for reading. I hope it brought something new to you. Hope you'll find a chance to give it a try for these features in your projects. Also, I would appreciate any feedback from you. Feel free to post your comments below.

The source code can be found here.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK