Swapping all elements of an array except for first and last

  • A+

I have an array that looks like this

const x = ['A','B','C','D','E'] 

I want to have an elegant function that would shuffle the content of the array but keeps the first or the last element fixed. Something like customShuffle(x) which will shuffle the array but ensures that the element "A" will be in the first position and the element "E" will be at the last position. All other elements are shuffled.

If the first and last elements of the array always stay in that same place, you can apply a normal shuffling algorithm, like a modern variation of Fisher and Yates', skipping those positions:

function customShuffle(arr) {   if (arr.length < 3) {     return arr;   }      // Note the -2 (instead of -1) and the i > 1 (instead of i > 0):      for (let i = arr.length - 2; i > 1; --i) {       const j = 1 + Math.floor(Math.random() * i);       [arr[i], arr[j]] = [arr[j], arr[i]];   }      return arr; }  console.log(customShuffle([1, 2, 3, 4, 5]).join(', ')); console.log(customShuffle(['A', 'B', 'C', 'D', 'E']).join(', '));
.as-console-wrapper {   max-height: 100vh; }

Otherwise, if you want to choose the first and last elements, as you pointed out in your original question, you can do something like this:

  1. Find the index of the elements you want to have in the first and last positions first: firstIndex and lastIndex.
  2. If those elements exist (they might not be present), remove them from the array.
  3. Apply a shuffling algorithm to the remaining elements (there's no need to also shuffle first and last).
  4. Add the first and last elements back into their place, if you need to.
function customShuffle(arr, first, last) {   // Find and remove first and last:      const firstIndex = arr.indexOf(first);     if (firstIndex !== -1) arr.splice(firstIndex, 1);        const lastIndex = arr.indexOf(last);   if (lastIndex !== -1) arr.splice(lastIndex, 1);      // Normal shuffle with the remainign elements using ES6:      for (let i = arr.length - 1; i > 0; --i) {       const j = Math.floor(Math.random() * (i + 1));       [arr[i], arr[j]] = [arr[j], arr[i]];   }      // Add them back in their new position:      if (firstIndex !== -1) arr.unshift(first);   if (lastIndex !== -1) arr.push(last);      return arr; }  console.log(customShuffle([1, 2, 3, 4, 5], 5, 1).join(', ')); console.log(customShuffle(['A', 'B', 'C', 'D', 'E'], 'E', 'C').join(', ')); console.log(customShuffle([1, 2, 3, 4, 5], 10, 20).join(', '));
.as-console-wrapper {   max-height: 100vh; }


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: