Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to print out a reversed array using range?

Tags:

c#

range

c#-8.0

Currently I'm sort of playing with this new c# 8.0 feature which is ranges.

And so far I have a question. Am I allowed to create a range from the end to the beginning ?

Lets say I have an array and I would like to print it out in reversed direction via range:

static void Test()
{
    int[] array = new int[10];
    for (int i = 0; i < 10; i++) array[i] = i;
    Range range = ^1..0;

    foreach (int v in array[range]) WriteLine(v);
}

But it gets me a runtime error - System.OverflowException: 'Arithmetic operation resulted in an overflow.' So am I right that the only one direction(from the beginning to the end) is allowed for ranges ?

like image 607
isxaker Avatar asked Mar 16 '19 19:03

isxaker


People also ask

How do I print a reverse range?

If you wrap range() inside reversed() , then you can print the integers in reverse order. range() makes it possible to iterate over a decrementing sequence of numbers, whereas reversed() is generally used to loop over a sequence in reverse order. Note: reversed() also works with strings.

How do I print an inverted array?

To print an array in reverse order, we shall know the length of the array in advance. Then we can start an iteration from length value of array to zero and in each iteration we can print value of array index. This array index should be derived directly from iteration itself.

How do you reverse the range of a list in Python?

reverse() method! The built-in reversed() function reverses the order of a list and lets you access each individual item one at a time. The reversed() function accepts a list as an argument and returns an iterable, reversed version of the items contained in the list.

How to print the elements of an array in reverse order?

Q. Program to print the elements of an array in reverse order. In this program, we need to print the elements of the array in reverse order that is; the last element should be displayed first, followed by second last element and so on. Above array in reversed order: Declare and initialize an array.

How to reverse an array in Python?

However, unlike other programming languages, arrays aren't a built-in data structure in Python. Instead, you use lists, and Python offers a few ways to reverse them. Using this built-in Python method, the list changes in place. This means that the original order of the list is affected. The initial order of the items gets updated and altered.

What is the reverse of range in Python?

Notice that the reverse of Python range is simplifying creating a new range but this time the last element of the previous range will be the first element and will return all other elements in reverse order. What is the Python range () method? Before going into the reverse of the Python range, first, let us understand the range () method.

How do you print an array in order in algorithm?

Algorithm 1 START 2 INITIALIZE arr [] = {1, 2, 3, 4, 5} 3 PRINT "Original Array:" 4 REPEAT STEP 5 for (i=0; i&lt;arr.length ; i++) 5 PRINT arr [i] 6 PRINT "Array in reverse order" 7 REPEAT STEP 8 for (i= arr.length-1; i&gt;=0; i--) 8 PRINT a [i] 9 END


Video Answer


2 Answers

Reverse ranges are not so much a limitation on the Range type, but rather a limitation on the Span (and related) types – which assume a positive increment. The rational is that many of the low-level optimizations and usage scenarios for a slice of an array are only geared toward the basic notion of a "pointer plus size". (Link to Range usages in Framework)

While this won't allow a reverse Span to be passed around, an extension method could be used to provide an easy and performant syntax for reverse range enumeration:

public static class RangeExtensions
{
    public static int Normalize(this Index index, int length) => 
           index.IsFromEnd ? length - index.Value : index.Value;

    public static (int start, int end) Normalize(this Range range, int length) => 
           (range.Start.Normalize(length), range.End.Normalize(length));

    public static IEnumerable<T> Enumerate<T>(this T[] items, Range range)
    {
        var (start, end) = range.Normalize(items.Length);

        return start <= end ? items[range] : GetRangeReverse();

        IEnumerable<T> GetRangeReverse()
        {
            for (int i = start; i >= end; i--)
                yield return items[i];
        }
    }
}

...

var numbers = Enumerable.Range(0, 10).ToArray();

foreach (var num in numbers.Enumerate(^3..1))
    Console.WriteLine(num);
like image 103
Andrew Hanlon Avatar answered Oct 23 '22 16:10

Andrew Hanlon


I couldn't find anything that says that's possible. But, it doesn't appear to be a language restriction, as we can create a range like Range r = 5..1; and that doesn't throw exceptions, so it must be the implementation of Array[Range] and other types, like string that doesn't accept it. That put, you can probably create an method that accepts a Range and does what you want.

Edit: I made the following method that works with arrays:

static T[] MySlice<T>(T[] array, Range r)
{
    //Transforms indexes "from end" to indexes "from start"    
    if(r.Start.IsFromEnd){
        var startIdx = array.Length - r.Start.Value;
        r = new Range(startIdx,r.End);
    }
    if(r.End.IsFromEnd){
        var endIdx = array.Length - r.End.Value;
        r = new Range(r.Start,endIdx);
    }
    //Check if start value is greater than end value. If so, invert it
    if(r.Start.Value > r.End.Value)
    {                
        r = new Range(r.End,r.Start);
        var invArr = array[r];
        Array.Reverse(invArr);
        return invArr;
    }
    return array[r];
}

And you can use like

int[] arr = Enumerable.Range(0,10).ToArray();
Range r = ^0..0;

foreach(var v in MySlice(arr,r)){
    Console.WriteLine(v);
}

Which outputs:

9
8
7
6
5
4
3
2
1
0
like image 44
Magnetron Avatar answered Oct 23 '22 16:10

Magnetron