2017-02-15 99 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))

純功能性,可讀性,雖然有點長[交換兩個