Checking if an array can be rotated to equal another in JavaScript I needed to write a function in JavaScript which checks if any rotation of an array is equal to another array.

By rotation, I mean:

rotate [1, 2, 3] --&gt; [3, 1, 2]
rotate [3, 1, 2] --&gt; [2, 3, 1]
rotate [2, 3, 1] --&gt; [1, 2, 3]


Here's the code for my function. It feels pretty verbose, especially since the array functions added by ES6 seem perfect for this sort of thing, yet I've used very few of them. In particular, using a label on the outer loop feels wrong.

Is there any way I can make this function shorter and/or faster?

/**
 * Taking two arrays, checks whether one may be rotated so that it equals
 * the other.
 */
function arraysEqualByRotation(first, second) {
  if (first.length !== second.length) {
    return false;
  }

  // We'll rotate the first continually and compare it to the second
  var rotatedFirst = first.slice(0);

  outer:
  for (var rotateCounter = 0; rotateCounter &lt; rotatedFirst.length; rotateCounter++) {
    // Rotate the array
    rotatedFirst.unshift(rotatedFirst.pop());

    // Check if their elements are equal
    for (var i = 0; i &lt; rotatedFirst.length; i++) {
      if (rotatedFirst[i] !== second[i]) {
        // Try another rotation
        continue outer;
      }
    }

    // At this stage, they're equal
    return true;
  }

  // At this stage, a matching combination was never found
  return false;
}


Example inputs and outputs:

first      | second     | result
-----------------------------------------------
[1, 2, 3]  | [1, 2, 3]  | true (same array)
[1, 2, 3]  | [3, 1, 2]  | true (rotate once)
[1, 2, 3]  | [2, 3, 1]  | true (rotate twice)
[1, 2]     | [1, 2, 3]  | false (different lengths)
[1, 2, 3]  | [1, 3, 2]  | false (no valid rotation)
I have not looked too deeply into the problem and I am guessing that there may be some function that produces a unique hash based on the sequence and independent of starting position. That would then only require that you iterate each array to create the hash and then compare to see if they match. That would give you a O(2n) solution where n is the size of one of the arrays.

If such hashing function does not exist, the brute force approch can easily be divided up and done in parallel. In javascript you would use webWorkers

There is also the approch that can use the GPU and the basic canvas 2D API but that has some limits on the size of the input arrays and the integer size of the values. Or via WebGL which is a little more flexible, but again the bottle neck is converting the arrays to an appropriate data format that the GPU can handle. The are some libraries out there that simplify the process, but you would only start to see any gains for very large arrays.

So to make some minor changes to your solution. To remove the pop and unshift  you can use the % operator to cycle past the end back to the start (see inner loop) 

And the using continue to jump out of the loops is hacky to say the least. A little smarter logic and you don't need the goto in disguise.

So the function below is not an improvement in complexity, but rather a improvement of efficiency. 

function canRotate(a, b) {
    var pos, count;
    const len = a.length;
    if (len === b.length) { 
        pos = 0;
        while (pos &lt; len) {
            count = 0;
            while (count &lt; len &amp;&amp; a[count] === b[(pos + count) % len]) {
                count ++;
            }
            if (count === len) { return true }
            pos ++;
        }
    }
    return false;
}


You could also use a regExp to do the search but again its not an improvement in complexity, just less code, and may be a lot faster in many situations (however the joins may need a separator to work on all cases)

Just join the second array and double it by add to its self, then join the first and convert to a regExp (or use String.API ) to test if the first array has a match in the second.

function canRotate(a,b){
    if(a.length === b.length) { 
        const strB = b.join("");
        return new RegExp(a.join(""),"").test(strB+strB);
    }
    return false;
}


Or using a asymmetrical separator ie has two different characters.

function canRotate(a,b){
    if(a.length === b.length) {
        const jStr = "=&gt;"; 
        const strB = b.join(jStr);
        return new RegExp(a.join(jStr),"").test(strB + jStr + strB);
    }
    return false;
}


Update 
This answer assumes that the arrays contains positive values of the JS 32bit signed int. 

Obliviously you should take care with the regExp solutions and only use it if array content can be joined without breaking the sequence uniqueness, and does not contain regExp tokens.