2

I have a simple problem, but I am having a hard time getting the concept.

I have an array of doubles (doublesarray) and I want to slice the array so that I get the last "x" values.

x could be 2,5,7,12,etc

example:

doublesarray = {0,2,4,5,7,8,2,4,6};
doublesarray.slice(-4,-1);

output:
[8,2,4,6]


doublesarray.slice(-2,-1);
output:
[4,6]

Attempt:

I found some code online that slices, but it does not handle 2 negative inputs.

public static class Extensions
{
    /// <summary>
    /// Get the array slice between the two indexes.
    /// ... Inclusive for start index, exclusive for end index.
    /// </summary>
    public static T[] Slice<T>(this T[] source, int start, int end)
    {
        // Handles negative ends.
    if (end < 0)
    {
        end = source.Length + end;
    }
    int len = end - start;

    // Return new array.
    T[] res = new T[len];
    for (int i = 0; i < len; i++)
    {
        res[i] = source[i + start];
    }
    return res;
    }
}
user1681664
  • 1,771
  • 8
  • 28
  • 53

4 Answers4

2

Sorry for the inconvenience, I just figured it out. It took me to write it out here to get it.

for anyone in the future, all you do is:

doublesarray.slice(doublesarray.Length-x,doublesarray.Length);
rhughes
  • 9,257
  • 11
  • 59
  • 87
user1681664
  • 1,771
  • 8
  • 28
  • 53
1

Yes, the code you've shown already handles a negative end:

if (end < 0)
{
    end = source.Length + end;
}

So all you've got to do is the same thing for start:

if (start < 0)
{
    start = source.Length + start;
}

(Or use +=, i.e. start += source.Length.)

Note that this still won't handle large negative values - only values as far as -source.Length.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0

You could also use Linq, since arrays are IEnumerable.

using Take, Reverse, and (if and only if you MUST have an array) ToArray

public static double[] slice(this double[] source, int count)
{
    if(Math.Abs(count) > source.Length) throw new ArgumentOutOfRangeException("Count");

    if(count > 0)
        return source
            .Take(count)
            .ToArray();
    else if(count < 0)
        return source
            .Reverse()
            .Take(count * -1)
            .Reverse
            .ToArray();
    else return new double[] { };
}

also consider using Skip if you need an implementation which goes a few paces back or forwards.

David
  • 10,458
  • 1
  • 28
  • 40
0

I would probably use Linq and do:

using System.Collections.Generic;
using System.Linq;

...

var doublesarray = new double[] { 0, 2, 4, 5, 7, 8, 2, 4, 6 };
var slicedarray = doublesarray.Skip(5).Take(4);

You will end up with a IEnumerable<double>

You can demo it in CompileOnline.com by simply copy/paste the code below and press "Compile & Execute" button

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        var doublesarray = new double[] { 0, 2, 4, 5, 7, 8, 2, 4, 6 };

        Log(doublesarray);

        IEnumerable<double> slicedarray = doublesarray.Skip(5).Take(4);

        Log(slicedarray);
    }

    static void Log(IEnumerable<double> doublesarray)
    {
        foreach (var d in doublesarray)
            Console.WriteLine(d);
        Console.WriteLine("-----");
    }
}

enter image description here

balexandre
  • 73,608
  • 45
  • 233
  • 342