Proper way to shift elements in int[] array

C# code
I want to shift my elements in an int array to the left by one.
Scenario:
[1,3,4,5] → [3,4,5,1]

[1,0,0,0] → [0,0,0,1]

etc…

Is there any built-in/algorithm which does this?

*EXTRA
If I want to show the shifted array on my UI with all the leading zeroes removed but still remember the original array so when i shift it again it will remember the amount of zeroes., how would one implement that?

Scenario:

[1,0,0,0] (UI Value: 1000)(Shift)[0,0,0,1] (UI Value: 1)(Shift)[0,0,1,0](UI Value: 10) etc…

Its as simple as creating a new array and copying the elements across one by one with a for loop.

However this is certainly an interesting way to do things. What is your use case for this? There probably is a much better option.

1 Like

I think this would be a pretty good place for an extension method if he just wants to return an array that is shifted. Should be easy enough to do with some simple for loop iteration as you said.

I just threw this together really quick for you; this is what you are asking for. Just make sure you put this in a static non-generic class.

public static int[] Shift(this int[] myArray){
        int[] tArray = new int[myArray.Length];
        for(int i = 0; i < myArray.Length; i++){
            if(i < myArray.Length - 1)
                tArray[i] = myArray[i + 1];
            else
                tArray[i] = myArray[0];
        }
        return tArray;
    }

//Example usage

int[] myArray = new int[]{1, 0, 0, 0};
int[] tArray = myArray.Shift();
3 Likes

Also, for the UI thing, this method should return a string that follows the correct format. Be aware that this is not an extension and you will need to call this method from the containing class or a reference thereto

private string StringFromIntArray (int[] myArray) {
            bool nonZero = false;
            string tString = string.Empty;
            for (int i = 0; i < myArray.Length; i++) {
                if(!nonZero){ 
                    if(myArray[i] != 0){
                        nonZero = true;
                        i--;
                    }
                } else {
                    tString += myArray[i].ToString();
                }
             
            }
            return tString;
        }

Best of luck to you!

I think it’s faster to use Array.Copy

public static int[] Shift(this int[] myArray)
{
        int[] tArray = new int[myArray.Length];
        int v = myArray[0];
        Array.Copy(myArray, 1, tArray, 0, myArray.Length - 1);
        tArray[tArray.Length - 1] = v;
        return tArray;
}

Another option is to use a Queue or LinkedList both let you easily remove an item at the front and add it to the back.

Queue<int> q = new Queue<int>( ... );
int v = q.Dequeue();
q.Enqueue(v);

// ------

LinkedList<int> l = new LinkedList<int>( ... );
int v = l.First();
l.RemoveFirst();
l.AddLast(v);
4 Likes

Thanks for the tip. I’m going to run some testing on each of these methods and drill down which one is actually the fastest. Could be very helpful in optimization situations!

If you are merely shifting data around like in your example, and not actually adding and removing data then I would simply shift an offset that points to the data. The data doesn’t need to change, only the way you are looking at it.

2 Likes

Yup. That’s included in the “much better option based on use case”

There’s more than one way to skin a cat I suppose. I personally would not shift the data in the array. I would probably just use an offset as @Hikiko66 stated; I’m just here to answer questions. If someone asks what is possible and I can show them how it can be done I will do just that. I can’t just assume that I know everything they are trying to do and there are probably situations where you may actually want to shift data; though this probably isn’t one of those cases. :slight_smile:

My first thought was simply to set up a custom data class. Use an array or list as the underlying type, and provide two different accessors, one that returns the normal data, and one that returns the shifted data.

But there might be a reason to want a copy instead of just faking it this way.

I’ve written a few classes that test how long it takes to complete a method or section of code and log it to the debug console if anyone is interested. Apparently my laptop takes ~420ms to populate an int[5000000] array with random numbers. :frowning:

I can post these if anyone is interested in using them

Moreover, the copying method to shift that data executes in ~12ms and the brute force iteration takes ~65ms

1 Like

It occurs to me that this is thread is quickly drifting away from the OP and becoming a discussion on code optimization. I’ve done some testing and I am going to post my findings and methodology in a new thread. I’ll drop a link in here when I’ve finished. Cheers!

im spawning random integer values that the player should use to hit a certain number with.
The problem i’m addressing should be used when right clicking ANY value in the game
I think the queue option is pretty nice. How efficient is it?

Shifting of that data is VERY efficient. My findings averaged less than 1ms; however, it is not the most quickly populated. I’m working on a thread right now that gives specifics, methodology, and even the source code I used to test this. As I said, I’ll link back here once I’ve finished the thread, so be on the lookout! In the mean time, feel free to use the queue. It’s definitely a viable option.

1 Like

Okay thanks

How many numbers will there be? I’m guessing whichever of the methods above would be efficient enough, and you should choose the one that makes your code the most readable.

You can do the queue even without a temporary variable q.Enqueue(q.Dequeue())

1 Like

I’ve just posted a report containing my findings in this thread: Code Optimization Practices - Unity Engine - Unity Discussions

Feel free to pop over there and give some input guys!

1 Like