Javascript:将对象从一个数组移动到另一个数组:最佳方法?

时间:2015-08-07 23:23:35

标签: javascript arrays angularjs

我有两个数组,称为'对象'和' appliedObjects'。我试图用Javascript和/或Angular中的优雅方式将对象从一个数组移动到另一个数组。

最初我做了类似的事情:

   $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);
            }
        });
    }

但后来我意识到当从循环数组中删除该值时,它不会添加或删除所有其他项,因为它是按索引进行的。

然后我尝试使用临时数组来保存要添加或删除的项目列表,我开始得到奇怪的参考问题。

我开始关注这个问题的最佳解决方案......任何帮助和/或指导都会非常感激。

7 个答案:

答案 0 :(得分:12)

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

答案 1 :(得分:6)

当一个构造自动执行太多时(比如forEach,或者甚至是for循环,在这种情况下),使用一个更原始的构造,允许你说清楚应该发生什么,而不需要解决构造。使用while循环,您可以表达需要执行的操作,而无需使用备份或以其他方式应用变通方法:

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

答案 2 :(得分:0)

如果你想简单地移动整个数组,你可以这样做:

appliedObjects = objects;
objects = []

当然,如果它们是函数的参数,它将无法工作! 否则我看不到除了在循环中复制之外的其他方式,例如

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

或者如果您喜欢短代码:):

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

检查小提琴http://jsfiddle.net/060ywajm/

答案 3 :(得分:0)

你在迭代它时改变数组,你总会错过一些元素。

这样做的一种方法是使用第三个数组来存储需要从数组中删除的对象的引用:

// "$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);
});

答案 4 :(得分:0)

现在这可能不是一个公平的答案,但是如果你注意到你正在做很多复杂的对象/数组操作,那么你应该看看lodash或下划线库。然后你可以用衬垫来解决这个问题:

//lodash remove function
appliedObjects.push.apply( appliedObjects, _.remove(objects, { 'selected': true}));

//or if you want to insert in the beginning of the list:
appliedObjects.splice(0, 0, _.remove(objects, { 'selected': true}));

答案 5 :(得分:0)

这是我觉得对你有用的第一关。我正在制作一个测试页面,以便我可以测试工作的准确性,并更新调整后的结果,希望不会有。

编辑:我运行它,如果我正确理解了问题,它似乎可以做你想要的事情。我编辑了几个语法错误。

这是使用精简,清理的代码http://plnkr.co/edit/K7XuMu?p=preview

的插件

HTML

<button ng-click="transferArrays(objects, appliedObjects)">Add</button>
<button ng-click="transferArrays(appliedObjects, objects)">Remove</button>

JS

$scope.transferArrays = function (arrayFrom, arrayTo) {
var selectedElements;
selectedElements = [];
angular.forEach(arrayFrom, function(element) {
  if (element.isSelected) {
    element.isSelected = false;
    selectedElements.push(element);
  }
});
angular.forEach(selectedElements, function(element) {
  arrayTo.push(arrayFrom.splice(
    arrayFrom.map(function(x) {
      return x.uniqueId;
    })
    .indexOf(element.uniqueId), 1));
});
};

旧代码

$scope.remove = function () {
        var selectedElements;
        selectedElements = [];
        angular.forEach($scope.appliedObjects, function (element) {
            if (element.isSelected) {
                element.isSelected = false;
                selectedElements.push(element);
            }
        });
        angular.forEach(selectedElements, function (element) {
            $scope.objects.push($scope.appliedObjects.splice(
                $scope.appliedObjects.map(function  (x) { return x.uniqueId; })
                .indexOf(element.uniqueId), 1));
        });
    };

$scope.add = function () {
        var selectedElements;
        selectedElements = [];
        angular.forEach($scope.objects, function (element) {
            if (element.isSelected) {
                element.isSelected = false;
                selectedElements.push(element);
            }
        });
        angular.forEach(selectedElements, function (element) {
            $scope.appliedObjects.push($scope.objects.splice(
                $scope.objects.map(function  (x) { return x.uniqueId; })
                .indexOf(element.uniqueId), 1));
        });
    };

答案 6 :(得分:0)

只需准备检查功能,您就可以使用此oneliner任意多次从arr1移到arr2的项目

arr2.push(arr1.splice(arr1.findIndex(arr1El => check(arr1El)),1)[0])