React-sortable-hoc: ArrayMove mutates array

Created on 26 Sep 2016  路  6Comments  路  Source: clauderic/react-sortable-hoc

All 6 comments

Completely agree. However, the other solutions I looked at were incredibly expensive. Happy to review any PR you may have that would solve this 馃憤

Thankfully arrayMove is an opt-in helper, so you're free to use your own implementation as well

Why not just 'copy' the array? const new = [].concat(array)

Here are three possible implementations of an immutable arrayMove.
On Chrome v53 arrayMoveImmutable() is the fastest.
But on Firefox v49 arrayMoveCopy() is the fastest (and the arrayMoveImmutableReverse() is faster then arrayMoveImmutable()).

function arrayMoveCopy(array, previousIndex, newIndex) {
  return arrayMove(array.slice(), previousIndex, newIndex);
}

function arrayMoveImmutable(array, previousIndex, newIndex) {
  var length = array.length;
  var newLength = newIndex >= length ? newIndex + 1 : length;
  var newArray = new Array(newLength);
  var element = array[previousIndex];

  for (var i = 0, j = 0; i < newLength; i++) {
    if (i === newIndex) {
      newArray[i] = element;
    } else {
      if (j === previousIndex) {
        j++;
      }

      if (j < length) {
        newArray[i] = array[j++];
      } else {
        newArray[i] = undefined;
      }
    }
  }

  return newArray;
}

function arrayMoveImmutableReverse(array, previousIndex, newIndex) {
  var length = array.length;
  var newLength = newIndex >= length ? newIndex + 1 : length;
  var newArray = new Array(newLength);
  var element = array[previousIndex];
  var i = newLength;
  var j = newLength;

  while (i--) {
    if (i === newIndex) {
      newArray[i] = element;
    } else {
      j--;
      if (j === previousIndex) {
        j--;
      }

      if (j < length) {
        newArray[i] = array[j];
      } else {
        newArray[i] = undefined;
      }
    }
  }

  return newArray;
}

@zaygraveyard my solution was based on slicing and concating array parts, but your solution with one level loop should have better performance

I've created a simple solution for this issue here, but i guess we better measure performance for every example above, so we can understand which implementation is the fastest.

Thanks for your PR @canvaskisa, it's been merged back into master.

Regarding performance concerns: I think if performance is a real concern for your application (for instance, if you have an array with millions of records), you're free to opt out and use your own implementation, as arrayMove is just a convenient, opt-in helper.

Thanks for your input everyone

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sami616 picture sami616  路  4Comments

Jessidhia picture Jessidhia  路  4Comments

zaygraveyard picture zaygraveyard  路  3Comments

dlee picture dlee  路  4Comments

ashishtechuz picture ashishtechuz  路  4Comments