I'm trying to swap 2 elements within an array in a functional way in javascript (es6)
let arr = [1,2,3,4,5,6]
let result = swap(arr, 1, 2) // input: array, first element, second element
// result=[1,3,2,4,5,6]
The only way I could think about is:
const swap = (arr, a, b) =>
arr.map( (curr,i) => i === a ? arr[b] : curr )
.map( (curr,i) => i === b ? arr[a] : curr )
But this code runs twice over the array, and not readable at all. Any suggestions for a nice clean functional code?
Thanks.
I'm trying to swap 2 elements within an array in a functional way in javascript (es6)
let arr = [1,2,3,4,5,6]
let result = swap(arr, 1, 2) // input: array, first element, second element
// result=[1,3,2,4,5,6]
The only way I could think about is:
const swap = (arr, a, b) =>
arr.map( (curr,i) => i === a ? arr[b] : curr )
.map( (curr,i) => i === b ? arr[a] : curr )
But this code runs twice over the array, and not readable at all. Any suggestions for a nice clean functional code?
Thanks.
Share Improve this question asked Feb 15, 2017 at 19:57 HasholefHasholef 7533 gold badges10 silver badges18 bronze badges 3 |7 Answers
Reset to default 10Short and reliable but admittedly hard to read:
const swap = (x, y) => ([...xs]) => xs.length > 1
? ([xs[x], xs[y]] = [xs[y], xs[x]], xs)
: xs;
const xs = [1,2,3,4,5];
const swap12 = swap(1, 2);
console.log(
swap12(xs),
"exception (one element):",
swap12([1]),
"exception (empty list):",
swap12([])
);
One 'map' would do it also:
function swap(arr, a, b) {
return arr.map((current, idx) => {
if (idx === a) return arr[b]
if (idx === b) return arr[a]
return current
});
}
How about the good ol'
const a = [1,2,3,4,5]
const swap = (start, end, arr) =>
[].concat(
arr.slice(0, start),
arr.slice(end,end+1),
arr.slice(start+1,end),
arr.slice(start,start+1)
)
console.log(swap(2, 4, a))
Purely functional, readable, albeit a bit long
You can use destructuring assignment to swap indexes of an array. If expected result is new array, call Array.prototype.slice()
on array passed to swap()
, else omit let copy = _arr.slice(0)
and reference _arr
arr destructuing assignment.
let arr = [1,2,3,4,5,6];
let swap = (_arr, a, b) => {
let copy = _arr.slice(0);
[copy[a], copy[b]] = [copy[b], copy[a]];
return copy
};
let result = swap(arr, 1, 2);
console.log(result, arr);
What a fun little problem – care should be taken to ensure that a
and b
are valid indices on xs
, but I'll leave that up to you.
const swap = (a,b) => (arr) => {
const aux = (i, [x, ...xs]) => {
if (x === undefined)
return []
else if (i === a)
return [arr[b], ...aux(i + 1, xs)]
else if (i === b)
return [arr[a], ...aux(i + 1, xs)]
else
return [x, ...aux(i + 1, xs)]
}
return aux (0, arr)
}
let xs = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
// same index doesn't matter
console.log(swap(0,0) (xs)) // [a, b, c, d, e, f, g]
// order doesn't matter
console.log(swap(0,1) (xs)) // [b, a, c, d, e, f, g]
console.log(swap(1,0) (xs)) // [b, a, c, d, e, f, g]
// more tests
console.log(swap(1,3) (xs)) // [a, c, d, b, e, f, g]
console.log(swap(0,6) (xs)) // [g, b, c, d, e, f, a]
console.log(swap(5,6) (xs)) // [a, b, c, d, e, g, f]
// don't fuck it up
console.log(swap(7,3) (xs)) // [a, b, c, undefined, e, f, g]
// empty list doesn't matter
console.log(swap(3,2) ([])) // []
ES2023 Array Method with():
The
with()
method ofArray
instances is the copying version of using the bracket notation to change the value of a given index. It returns a new array with the element at the given index replaced with the given value.
let arr = [1,2,3,4,5,6]
function swap(arr, x, y){
return arr.with(x, arr[y]).with(y, arr[x]);
}
let result = swap(arr, 1, 2)
console.log(result); //[1,3,2,4,5,6]
PS: with()
method is supported nearly by all browsers and on Node.js version 20+.
see browser compatibility
Returns new Array (Function-Programming):
const swap = (arr, a, b)=> { let copy = arr.slice(0); copy[b] = [copy[a], copy[a] = copy[b]][0]; return copy; }
Manipulate the input Array (Non Function-Programming):
const swap = (arr, a, b)=> { arr[b] = [arr[a], arr[a] = arr[b]][0]; return arr; }
arr.with(a, arr[b]).with(b, arr[a])
see my answer with an example! – XMehdi01 Commented Jun 11, 2023 at 11:03