Skip to content

Instantly share code, notes, and snippets.

@eerohele
Last active November 2, 2021 16:01
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save eerohele/5195815 to your computer and use it in GitHub Desktop.
Save eerohele/5195815 to your computer and use it in GitHub Desktop.
Swap two array elements (JavaScript)
/**
* Swap the elements in an array at indexes x and y.
*
* @param (a) The array.
* @param (x) The index of the first element to swap.
* @param (y) The index of the second element to swap.
* @return {Array} The input array with the elements swapped.
*/
var swapArrayElements = function (a, x, y) {
if (a.length === 1) return a;
a.splice(y, 1, a.splice(x, 1, a[y])[0]);
return a;
};
swapArrayElements([1, 2, 3, 4, 5], 1, 3); //=> [ 1, 4, 3, 2, 5 ]
@sillyslux
Copy link

A new array with the elements swapped.

This is not true, Array#splice is a mutating method, thus it's returning the same, but modified array.
With ES6 you could use this function:

const swapArrayElements = (a, x, y) => a[x] && a[y] && [
  ...a.slice(0, x),
  a[y],
  ...a.slice(x+1, y),
  a[x],
  ...a.slice(y+1)
] || a

(it's not exactly the same, it will simply return the array, when a given index x or y is undefined)

@beausmith
Copy link

beausmith commented Apr 4, 2018

👍 @sillyslux

The array I'm working with contains booleans, so I had to update this ES6 solution to support boolean values in the array:

Swap boolean array values

const swapArrayElements = (a, x, y) => a[x] !== undefined && a[y] !== undefined && [
  ...a.slice(0, x),
  a[y],
  ...a.slice(x+1, y),
  a[x],
  ...a.slice(y+1)
] || a

One other caveat to the ES6 solution, x must have a lower index than y.

Swap array indexes regardless of if x is greater than y

const swapArrayElements = (arr, x, y) => {
  if (arr[x] === undefined || arr[y] === undefined) {
    return arr
  }
  const a = x > y ? y : x
  const b = x > y ? x : y
  return [
    ...arr.slice(0, a),
    arr[b],
    ...arr.slice(a+1, b),
    arr[a],
    ...arr.slice(b+1)
  ]
}

@hmccabe2002
Copy link

var arr = [1,2,3,4];
var arr2 = [5,6,7,8];

How could i switch the values of arrays so arr becomes arr = [5,6,7,8]; and arr2 becomes arr2 = [1,2,3,4];?

@eerohele
Copy link
Author

@sillyslux: Thanks for the correction! I fixed the comment.

(On a side note, I really wish GitHub sent notifications when someone comments on your Gist.)

@beephotography
Copy link

beephotography commented Oct 27, 2019

Another non-mutative ES6y version could be:

const swap = (arr, index1, index2) => arr.map((val, idx) => {
  if (idx === index1) return arr[index2];
  if (idx === index2) return arr[index1];
  return val;
});
const foo = [1, 2, 3, 4, 5];
const swapped = swap(foo, 1, 3); 
console.log(foo); //=> [1, 2, 3, 4, 5]
console.log(swapped); //=> [ 1, 4, 3, 2, 5 ]

@yi-ren-brokerbay
Copy link

Another non-mutative ES6y version could be:

const swap = (arr, index1, index2) => arr.map((val, idx) => {
  if (idx === index1) return arr[index2];
  if (idx === index2) return arr[index1];
  return val;
});
const foo = [1, 2, 3, 4, 5];
const swapped = swap(foo, 1, 3); 
console.log(foo); //=> [1, 2, 3, 4, 5]
console.log(swapped); //=> [ 1, 4, 3, 2, 5 ]

good way to change from O(1) to O(n)👍🏾

@blackavec
Copy link

initial code seems more reasonable to me than this last one.
of course the code works but does it make sense to brute force the arr in order to swap two indexes?
what if list is large and you want to swap two indexes at the beginning and end of the list? seems a bit naive to me.
it's possible that i'm not seeing the wisdom in it so feel free to clarify if i'm wrong ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment