![](/img/trans.png)
[英]move one specific object prop from one array to another array of objects, if condition (JavaScript ES6)
[英]Javascript: move objects from one array to another: Best approach?
我有两个 arrays,分别称为“对象”和“应用对象”。 我试图在 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);
}
});
}
但是后来我意识到,当从循环数组中删除该值时,它不会添加或删除所有其他项目,因为它是按索引进行的。
然后我尝试使用一个临时数组来保存要添加或删除的项目列表,我开始遇到奇怪的引用问题。
我开始讨论这个问题的最佳解决方案是什么......任何帮助和/或指导将不胜感激。
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);
}
当一个构造自动执行太多操作时(例如 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++;
}
}
如果你想简单地移动整个数组,你可以这样做:
appliedObjects = objects;
objects = []
当然如果它们是函数的参数就行不通了! 否则我看不到除了在循环中复制之外的其他方式,例如
while (objects.length) {
appliedObjects.push(objects[0]);
objects.splice(0,1);
}
或者如果你喜欢短代码 :) :
while (objects.length) appliedObjects.push(objects.splice(0,1));
您在迭代数组时正在更改数组,您总会错过一些元素。
一种方法是使用第三个数组来存储需要从数组中删除的对象的引用:
// "$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);
});
现在这可能不是一个公平的答案,但如果你注意到你正在做很多复杂的对象/数组操作,你真的应该查看 lodash 或 underscore 库。 那么你可以用在线解决这个问题:
//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}));
这是我认为对你有用的第一遍。 我正在制作一个测试页面,以便我可以测试工作的准确性并更新调整后的结果,希望不会有。
编辑:我运行了它,如果我正确理解了问题,它似乎可以满足您的需求。 我编辑了几个语法错误。
这是带有压缩、清理过的代码的 plunk 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));
});
};
您可以多次使用此 oneliner 将需要从 arr1 移动到 arr2 的项目数量,只需准备检查功能
arr2.push(arr1.splice(arr1.findIndex(arr1El => check(arr1El)),1)[0])
您可以使用它来连接 2 个 arrays。 让 array3 = [...array1, ...array2];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.