简体   繁体   English

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

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

I have two arrays, called 'objects' and 'appliedObjects'.我有两个 arrays,分别称为“对象”和“应用对象”。 I'm trying to come up with an elegant way in Javascript and/or Angular to move objects from one array to another.我试图在 Javascript 和/或 Angular 中提出一种优雅的方式来将对象从一个数组移动到另一个数组。

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.我开始讨论这个问题的最佳解决方案是什么......任何帮助和/或指导将不胜感激。

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

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.当一个构造自动执行太多操作时(例如 forEach,甚至在这种情况下是 for 循环),请使用更原始的构造,它允许您清楚地说明应该发生什么,而无需解决该构造。 Using a while loop, you can express what needs to happen without resorting to backing up or otherwise applying workarounds:使用 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++;
    }
}

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, eg否则我看不到除了在循环中复制之外的其他方式,例如

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/检查小提琴http://jsfiddle.net/060ywajm/

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

Now this maybe is not a fair answer, but if you notice you are doing alot of complicated object/array manipulations, you should really check out lodash or underscore library.现在这可能不是一个公平的答案,但如果你注意到你正在做很多复杂的对象/数组操作,你真的应该查看 lodash 或 underscore 库。 then you could solve this with on liner:那么你可以用在线解决这个问题:

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

This is a first pass at what I think will work for you.这是我认为对你有用的第一遍。 I'm in the process of making a test page so that I can test the accuracy of the work and will update the tweaked result, which hopefully there will not be.我正在制作一个测试页面,以便我可以测试工作的准确性并更新调整后的结果,希望不会有。

EDIT: I ran it and it seems to do what you are wanting if I understand the problem correctly.编辑:我运行了它,如果我正确理解了问题,它似乎可以满足您的需求。 There were a couple of syntax errors that I edited out.我编辑了几个语法错误。

Here's the plunk with the condensed, cleaned code http://plnkr.co/edit/K7XuMu?p=preview这是带有压缩、清理过的代码的 plunk http://plnkr.co/edit/K7XuMu?p=preview

HTML HTML

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

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

Old code旧代码

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

您可以多次使用此 oneliner 将需要从 arr1 移动到 arr2 的项目数量,只需准备检查功能

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

You can use this to concat 2 arrays.您可以使用它来连接 2 个 arrays。 let array3 = [...array1, ...array2];让 array3 = [...array1, ...array2];

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如果条件(JavaScript ES6),将一个特定的 object 道具从一个数组移动到另一个对象数组 - move one specific object prop from one array to another array of objects, if condition (JavaScript ES6) 将 object 值从一个对象数组移动到另一个对象数组 - Move object value from one array of objects to another 如何在 JavaScript 中从另一个数组中过滤一个数组中的对象? - How to filter objects from one array from another array in JavaScript? Javascript:尝试将项目从一个数组随机移动到另一个数组 - Javascript: Trying to randomly move items from one array to another JavaScript:有条件地将JSON对象从一个数组添加到另一个数组 - JavaScript: Add JSON objects from one array to another array conditionally 如何将 javascript 对象数组从一种格式转换为另一种格式? - How to convert a javascript array of Objects from one format to another format? 将所选对象从一个位置移到另一位置,然后再次移回原始位置 - Move selected objects from one place to another and back again to original position javascript 将房产从一个object移到另一个Javascript - Move a property from one object to another in Javascript 将对象从一个数组移动到另一个数组 - Move object from one array to another Javascript方法将第一个(对象)数组的属性复制到另一个不同长度的(对象)数组中 - Javascript approach to copy properties of first array(of objects) into another array(of objects) of different lengths
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM