Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript: move objects from one array to another: Best approach?

I have two arrays, called 'objects' and 'appliedObjects'. I'm trying to come up with an elegant way in Javascript and/or Angular to move objects from one array to another.

Initially I did something like this:

   $scope.remove = function () {
        angular.forEach($scope.appliedObjects, function (element, index) {
            if (element.selected) {
                element.selected = false;
                $scope.objects.push(element);
                $scope.appliedObjects.splice(index, 1);
            }
        });
    }

   $scope.add= function () {
        angular.forEach($scope.objects, function (element, index) {
            if (element.selected) {
                element.selected = false;
                $scope.appliedObjects.push(element);
                $scope.objects.splice(index, 1);
            }
        });
    }

But then I realized that when the value was removed from the looping array, and it would not add or remove every other item, since it went by index.

Then I tried using a temporary array to hold the list of items to be added or removed, and I started getting strange referential issues.

I'm starting to spin a bit on what the best solution to this problem would be...any help and/or guidance would much appreciated.

like image 447
morganpdx Avatar asked Aug 07 '15 23:08

morganpdx


People also ask

How do I move an array from one array to another?

Create a temp variable and assign the value of the original position to it. Now, assign the value in the new position to original position. Finally, assign the value in the temp to the new position.

What is Unshift method in JavaScript?

unshift() The unshift() method adds one or more elements to the beginning of an array and returns the new length of the array.


4 Answers

When a construct does too much automatically (like forEach, or even a for-loop, in this case), use a more primitive construct that allows you to say what should happen clearly, without need to work around the construct. Using a while loop, you can express what needs to happen without resorting to backing up or otherwise applying workarounds:

function moveSelected(src, dest)  {
    var i = 0;
    while ( i < src.length ) {
        var item = src[i];
        if (item.selected) {
            src.splice(i,1);
            dest.push(item);
        }
        else i++;
    }
}
like image 45
Ed Staub Avatar answered Oct 11 '22 17:10

Ed Staub


function moveElements(source, target, moveCheck) {
    for (var i = 0; i < source.length; i++) {
        var element = source[i];
        if (moveCheck(element)) {
            source.splice(i, 1);
            target.push(element);
            i--;
        }
    } 
}

function selectionMoveCheck(element) {
   if (element.selected) {
       element.selected = false;
       return true;
   }
}

$scope.remove = function () {
    moveElements($scope.appliedObjects, $scope.objects, selectionMoveCheck);
}

$scope.add = function () {
    moveElements($scope.objects, $scope.appliedObjects, selectionMoveCheck);
}
like image 130
Artem Avatar answered Oct 11 '22 18:10

Artem


You are altering the array while iterating on it, you will always miss some elements.

One way of doing it would be to use a third array to store the references of the objects that need to be removed from the array:

// "$scope.add" case
var objectsToRemove = [];

$scope.objects.forEach(function (value) {
  if (value.selected) {
    value.selected = false;
    $scope.appliedObjects.push(value);
    objectsToRemove.push(value);
  }
});

objectsToRemove.forEach(function (value) {
  $scope.objects.splice($scope.objects.indexOf(value), 1);
});
like image 1
Benoit Avatar answered Oct 11 '22 18:10

Benoit


If you wish to move simply whole array you could do:

appliedObjects = objects;
objects = []

Of course it won't work if they were parameters of a function! Otherwise I cannot see other way than copying in the loop, e.g.

while (objects.length) {
    appliedObjects.push(objects[0]);
    objects.splice(0,1);
}

or if you like short code :) :

while (objects.length) appliedObjects.push(objects.splice(0,1));

check fiddle http://jsfiddle.net/060ywajm/

like image 1
Zbyszek Swirski Avatar answered Oct 11 '22 16:10

Zbyszek Swirski