4

I m studying functional programming with javascript and I m having some problems dealing with value permutations.

Actually, I have an array that looks like:

[2, 1]

And I need to get functionally, with no mutation:

[1, 2]

This way, I've written a permute function that uses some ES6 features to makes the job:

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

Using this function, I always get

[1, 1]

And I don't understand why, because I first add the indiceY value at the indiceX place, and makes the same stuff just after but for the other value..

Any idea of what I m doing wrong?

EDIT : Some precisions, it should permute two items of an array of length N, for example :

permute([1, 3, 2, 6], 0,2) // should return [2, 3, 1, 6]

EDIT 2 : I've published the solution on my github account

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

Cœur
  • 37,241
  • 25
  • 195
  • 267
mfrachet
  • 8,772
  • 17
  • 55
  • 110
  • should it be just reversing of items? – RomanPerekhrest Jul 08 '16 at 06:51
  • 1
    May be first you assign first element to second index, then you get the second element which now actually is the originally first element. Now, you place it in first place as well, resulting in first element in both places. – Mohit Bhardwaj Jul 08 '16 at 06:51
  • The second time, I place it at indiceY with indiceX value, the opposite of the first time. So it should be the good value no ? – mfrachet Jul 08 '16 at 06:54
  • `[...data.reverse()]` – dfsq Jul 08 '16 at 06:54
  • I only need it for two values, but thank you for the example :-) – mfrachet Jul 08 '16 at 06:55
  • My bad , @MohitBhardwaj was right. Put it as anwser so that I can improve you :-) . Thanks for your help guys – mfrachet Jul 08 '16 at 07:04
  • @dfsq: Actually that *does* mutate `data` – Bergi Jul 08 '16 at 07:25
  • @Bergi You are right. `[...data].reverse()` would be better. – dfsq Jul 08 '16 at 07:35
  • 1
    I'm so confused... the only permutation for a 2-element list is the list in reverse. Why all the extra code? – Mulan Jul 08 '16 at 07:57
  • I ll precise that it should work with a bigger array, but thanks for the solutions – mfrachet Jul 08 '16 at 08:15
  • Since we work with Javascript, which isn't a purely functional language, we can risk a little mutation of local state: `const permute = xs => x => y => { const [...ys] = xs; return [ys[y], ys[x]] = [ys[x], ys[y]], ys }` –  Jul 08 '16 at 09:07

2 Answers2

2

In addition to @MohitBhardwaj's answer, if you limit yourself to 'functional' expressions, a solution could look as follows:

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];
}

But since you already use declarations, you could go for the 'real-world' solution by copying the input array and then following Javascript swap array elements

Community
  • 1
  • 1
le_m
  • 19,302
  • 9
  • 64
  • 74
1

May be first you assign first element to second index, then you get the second element which now actually is the originally first element. Now, you place it in first place as well, resulting in first element in both places.

Mohit Bhardwaj
  • 9,650
  • 3
  • 37
  • 64