最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Swap two array elements in a functional way - Stack Overflow

programmeradmin2浏览0评论

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
  • Possible duplicate of Swapping two items in a javascript array – Vaibhav Kumar Commented Feb 15, 2017 at 20:05
  • Is expected result a new array or swap of elements at original array? – guest271314 Commented Feb 15, 2017 at 20:07
  • ES2023 Array Method with() you can do it in one line: arr.with(a, arr[b]).with(b, arr[a]) see my answer with an example! – XMehdi01 Commented Jun 11, 2023 at 11:03
Add a comment  | 

7 Answers 7

Reset to default 10

Short 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 of Array 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; }
发布评论

评论列表(0)

  1. 暂无评论