JavaScript中,函数式地交换数组中的两个项。

4

我正在学习使用JavaScript进行函数式编程,但是我在处理值排列时遇到了一些问题。

实际上,我有一个类似于以下的数组:

[2, 1]

我需要获取功能性的内容,且不会进行任何修改:

[1, 2]

我写了一个使用一些ES6功能的排列函数来完成这项工作:

export function permute (arr, indiceX, indiceY) {
  const intermediateArray = [
    ...arr.slice(0, indiceX),
    arr[indiceY],
    ...arr.slice(indiceX + 1)
  ]

  console.log([
    ...intermediateArray.slice(0, indiceY),
    intermediateArray[indiceX],
    ...intermediateArray.slice(indiceY + 1)
  ]) // prints [1, 1]

  return [
    ...intermediateArray.slice(0, indiceY),
    intermediateArray[indiceX],
    ...intermediateArray.slice(indiceY + 1)
  ]
}

使用这个函数,我总是得到
[1, 1]

我不明白为什么,因为我首先在indiceX的位置添加了indiceY值,然后做了同样的事情但是针对另一个值。
你有任何想法我做错了什么吗?
编辑:一些细节,它应该交换长度为N的数组中的两个项目,例如:
permute([1, 3, 2, 6], 0,2) // should return [2, 3, 1, 6]

编辑 2 :我已在我的github账户上发布了解决方案

https://github.com/Skahrz/immutable-permute


1
也许你可以先将第一个元素赋值给第二个索引,然后获取第二个元素,它现在实际上是最初的第一个元素。现在,你也可以将其放在第一位,这样就会导致两个位置都有第一个元素。 - Mohit Bhardwaj
我只需要两个值,但还是谢谢你的示例 :-) - mfrachet
@Bergi 你是对的。[...data].reverse() 更好。 - dfsq
1
我很困惑... 一个包含两个元素的列表的唯一排列是反转后的列表。为什么还需要额外的代码? - Mulan
我想强调这应该适用于更大的数组,但还是感谢您提供的解决方案。 - mfrachet
显示剩余6条评论
2个回答

2
除了 @MohitBhardwaj 的回答之外,如果你将自己限制在“函数式”表达式中,解决方案可能如下所示:
function swap_ordered(a, i0, i1) {
  return [...a.slice(0, i0), a[i1], ...a.slice(i0+1, i1), a[i0], ...a.slice(i1+1)];
}

function swap(a, i0, i1) {
  return i0 != i1 ? swap_ordered(a, Math.min(i0, i1), Math.max(i0, i1)) : [...a];
}

但是,既然您已经使用了声明,那么您可以采用“真实世界”的解决方案,即复制输入数组,然后按照JavaScript交换数组元素的方法进行操作。


两个函数总比一个好:D - user6445533

1
也许你首先将第一个元素分配给第二个索引,然后获取第二个元素,这实际上是最初的第一个元素。现在,你也将它放在第一个位置,导致两个位置都有第一个元素。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接