-2

Is there something that will make it possible in C# create array for example int[6,10]. And always when i add new element [i,0] all elements in this row will shifted +1. And last will remove.

Now I had to do something like this:

 array[i, 2] = array[i, 1];
 array[i, 1] = array[i, 0];
 array[i, 0] = value;

Could it be better to use for example dictionary with int and List?

Edit: I not only move this data i will use this data to calculate something. So I think Queue wont be good for this.

I need it for method like this. In this method i do it only for array[6,2]. Now i think i need know more about my history. So i will have array[6,10]. I will check diferent cases and created dependencies. I need something to that it would look as clear as possible and work quickly.

 public static double CalculateLastValue(double value, KalmanModel k, int i)
    {
        if (k.LastDistance[i, 0] == 0 && k.LastDistance[i, 1]==0)
        {
            k.LastDistance[i, 0] = value;
            k.LastDistance[i, 1] = value;
        }
        if (k.LastDistance[i, 0] == k.LastDistance[i, 1])
        {

            if (Math.Abs(value - k.LastDistance[i, 0]) > 2 && value < k.LastDistance[i, 0])
            {
                value = k.LastDistance[i, 0] - 2;
            }
            else if (Math.Abs(value - k.LastDistance[i, 0]) > 2 && value > k.LastDistance[i, 0])
            {
                value = k.LastDistance[i, 0] + 2;
            }
            k.LastDistance[i, 1] = k.LastDistance[i, 0];
            k.LastDistance[i, 0] = value;
            return value;
        }
        else if (k.LastDistance[i, 0] > k.LastDistance[i, 1])
        {
            if (value >= k.LastDistance[i, 0])
            {
                if (Math.Abs(value - k.LastDistance[i, 0]) > 2)
                {
                    value = k.LastDistance[i, 0] + 2;
                }
                k.LastDistance[i, 1] = k.LastDistance[i, 0];
                k.LastDistance[i, 0] = value;
                return value;
            }
            else
            {
                value = k.LastDistance[i, 0];
                k.LastDistance[i, 1] = k.LastDistance[i, 0];
                return value;
            }
        }
        else 
        {
            if (value <= k.LastDistance[i, 0])
            {
                if (Math.Abs(value - k.LastDistance[i, 0]) > 2)
                {
                    value = k.LastDistance[i, 0] - 2;
                }
                k.LastDistance[i, 1] = k.LastDistance[i, 0];
                k.LastDistance[i, 0] = value;
                return value;
            }
            else
            {
                value = k.LastDistance[i, 0];
                k.LastDistance[i, 1] = k.LastDistance[i, 0];
                return value;
            }
        }
    }
Silny ToJa
  • 1,029
  • 1
  • 3
  • 13
  • 2
    Unless random access is a requirement it sound like you want a Queue. – Sean Nov 26 '19 at 09:56
  • 1
    [Queue solution](https://stackoverflow.com/questions/1292/limit-size-of-queuet-in-net) or [List solution](https://stackoverflow.com/questions/14702654/rolling-list-in-net) – A Friend Nov 26 '19 at 09:56
  • Have look at new C# 8 indices and ranges https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#indices-and-ranges – Pavel Anikhouski Nov 26 '19 at 09:56
  • 1
    What you want is too specific: there's not general container for that. You can implement it yourself easily. – JHBonarius Nov 26 '19 at 09:57
  • 1
    Isn't [rolling list](https://stackoverflow.com/questions/14702654/rolling-list-in-net) from A friend link a good dupe target? Or did I miss a requirement? – xdtTransform Nov 26 '19 at 10:01
  • At last i would do a lot of operations on this. Sorry i should wrote it. – Silny ToJa Nov 26 '19 at 10:02
  • why do you want a 2D array? i.e. `int[6,10]`? – JHBonarius Nov 26 '19 at 10:05
  • @xdtTransform The only difference is that Queue adds to the end, not the start.. But they could do some transformation when they "use this data to calculate something" – A Friend Nov 26 '19 at 10:06
  • Because i have 6 similar elements for one object and i had to know their last steps. – Silny ToJa Nov 26 '19 at 10:08
  • There is no high performance sliding array in the BLC, you will have to create an array and buffer copy it when and item is removed for performance. However in regaurds to performance, it depends if read performance means more to you then adding removing an item – TheGeneral Nov 26 '19 at 10:12
  • Dear @JHBonarius i update my post. Maybe now i will more understandable. – Silny ToJa Nov 26 '19 at 10:23
  • @TheGeneral I think I will spend more time extracting and comparing array elements than updating them. For this I think it should be a array, not a list or queue. So should i stay with array and only do method for update elements? – Silny ToJa Nov 26 '19 at 10:27

2 Answers2

1

There is no specific data structure for what you want. Furthermore, you already mentioned that adding elements will not occur often... so KIS: keep it simple.

You can write a helper function like:

public static void PushElement<T>(ref T[,] arr, int index, T value)
{
    var len1 = arr.GetLength(1);
    Array.Copy(arr, index * len1, arr, index * len1 + 1, len1 - 1);
    arr[index, 0] = value;
}

public static void Main()
{
    int[,] arr = { { 1, 2, 3 }, { 4, 5, 6 } };

    PushElement(ref arr, 1, 7);

arr[1,:] will now contain 7,4,5.

JHBonarius
  • 6,889
  • 3
  • 12
  • 28
0

There are no such data structures in .NET. But that doesn't mean what you need is impossible to build.

You should define your cycle length, n, and maintain a current_index which wraps around to 0 when it reaches n-1 index.

class wrapping_array
{
    public wrapping_array(int cycle)
    {
         n = cycle;
         array = new int[cycle];
    }

    public int this[int index]
    {
        get => array[index];
        set => array[index] = value;
    }

    int n, index;
    int[] array;

    public int insert(int value)
    {
        array[index++%n]=value;
    }
}
Tanveer Badar
  • 4,541
  • 2
  • 27
  • 31
  • There 100% are plenty of data structures that will do this – Liam Nov 26 '19 at 09:57
  • 1
    Care to link some in comments? – Tanveer Badar Nov 26 '19 at 09:58
  • [No need](https://stackoverflow.com/questions/59048068/i-am-looking-for-sliding-array#comment104337057_59048068) – Liam Nov 26 '19 at 09:59
  • Shouldn't the array access in `this[int index]` also be changed to `array[(this.index+index)%n]`? That would probably feel more "natural". And also throw if the requested index is `<0` or `>=n`? – Corak Nov 26 '19 at 10:24
  • I'm being annoying but you shouldn't use snake_case in C# if you want to follow the [official guidelines](https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/general-naming-conventions). – Joelius Nov 26 '19 at 11:18
  • @Corak No need to insert extra checks for range validation, array's indexer will already do that for us. Hence, only insertion requires that round-robin behavior. – Tanveer Badar Nov 26 '19 at 11:18
  • @Joelius Agreed. :) It was for illustration only, I don't expect anyone to include that in production/assignment code. – Tanveer Badar Nov 26 '19 at 11:19
  • @TanveerBadar - yes, you're right, of course. What do you think about using `array[(this.index+index)%n]`, though? How would you reliably get the "most recent" or "oldest" entry? – Corak Nov 26 '19 at 12:30