2017-02-15 14 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 n a javascript array] (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

One «карта» будет делать также:

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 destructuing assign.

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

Если ожидаемый результат - это оригинальные элементы массива, которые нужно изменить '.ll()' можно удалить ' пусть swap = (arr, a, b) => ([arr [a], arr [b]] = [arr [b], arr [a]]) && arr; ' – guest271314

-1

Возвращает новый массив (Function-программирование):

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

Манипулирование входного массива (Non Функционально-программирование):

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

мутирует' arr' - не в духе функционального программирования – naomik

+0

Редактирование ответа – sidanmor

1

Какая забавная маленькая проблема - следует позаботиться, чтобы гарантировать, что a и b являются действительными индексы на 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

Как насчет хорошего ола»

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

чисто функциональный, читаемым, хотя и немного долго

 Смежные вопросы

  • Нет связанных вопросов^_^