2017-02-15 77 views
2

我想换一个阵列内的2种元素在功能的方式在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] 

我能想到的唯一的办法是:

const swap = (arr, a, b) => 
      arr.map((curr,i) => i === a ? arr[b] : curr) 
       .map((curr,i) => i === b ? arr[a] : curr) 

但是这段代码在数组上运行两次,根本不可读。 任何建议一个漂亮的清洁功能代码?

谢谢。

+0

可能的复制物品i一个JavaScript的数组](http://stackoverflow.com/questions/4011629/swapping-two-items-in-a-javascript-array) –

+0

预期的结果是一个新的数组或在原始数组元素交换? – guest271314

回答

4

短而可靠的,但不可否认硬阅读:

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([]) 
 
);

+1

可爱。做得好 – naomik

+1

看起来不错!,虽然不起作用。这种方法的核心工作依赖于突变 – jgr0

+1

局部突变是好的。这是Javascript! – ftor

2

一个“地图”会做也:

function swap(arr, a, b) { 
    return arr.map((it, idx) => 
    (idx === a) ? arr[b] : 
    (idx === b) ? arr[a] : it 
); 
} 
+0

堆栈三元使它有点令人难以接受,但它是一个很好的实现 - 注意,用户应该适当谨慎地验证索引是否在范围 – naomik

0

你可以用解构赋值来交换一个数组的索引。如果预期的结果是新数组,则调用Array.prototype.slice()将数组传递给swap(),否则省略let copy = _arr.slice(0)并引用_arr arr破坏分配。

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);

+0

如果预期的结果是原始数组元素将被改变'.slice()'可以被移除' let swap =(arr,a,b)=>([arr [a],arr [b]] = [arr [b],arr [a]])&& arr;' – guest271314

-1

返回新的Array(函数编程):

const swap = (arr, a, b)=> { let copy = arr.slice(0); copy[b] = [copy[a], copy[a] = copy[b]][0]; return copy; } 

操纵输入数组(非功能编程):

const swap = (arr, a, b)=> { arr[b] = [arr[a], arr[a] = arr[b]][0]; return arr; } 
+0

变异'arr' - 函数式编程 – naomik

+0

我编辑答案 – sidanmor

1

一个有趣的小问题是什么 - 应该小心,以确保ab是有效的索引上xs,但我会离开,给你。

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) ([])) // []

2

如何好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))

纯功能性,可读性,虽然有点长[交换两个