Javascript 将匹配对象添加到另一个数组时,从数组中删除它们

Javascript 将匹配对象添加到另一个数组时,从数组中删除它们,javascript,arrays,Javascript,Arrays,我正在尝试构建一个三层功能: 首先,一个数组列出了可用的车间(数组称为“车间”)。 其次,另一个数组列出用户选择的车间(此数组称为“selectedWorkshops”)。 第三,我有一个名为“registeredWorkshops”的最终数组 运行我的功能时,我希望将“selectedWorkshops”中的对象添加到“registeredWorkshops”,然后从“selectedWorkshops”和“workshops”中的任何匹配元素中删除“selectedWorkshops”中的任

我正在尝试构建一个三层功能: 首先,一个数组列出了可用的车间(数组称为“车间”)。 其次,另一个数组列出用户选择的车间(此数组称为“selectedWorkshops”)。 第三,我有一个名为“registeredWorkshops”的最终数组

运行我的功能时,我希望将“selectedWorkshops”中的对象添加到“registeredWorkshops”,然后从“selectedWorkshops”和“workshops”中的任何匹配元素中删除“selectedWorkshops”中的任何对象。因此,如果这些对象过去同时存在于“SelectedWorkshop”和“Workshop”中,那么现在它们只存在于“RegisteredWorkshop”中

以下是到目前为止我得到的信息:

addRemoveWorkshops = function(){
    var numberOfWorkshops = selectedWorkshops.length;
    for(var i = 0; i < numberOfWorkshops; i++ ){
        registeredWorkshops.push(selectedWorkshops[i]);
        for(var j = 0, arrayLength = workshops.length; j < arrayLength; j++) {
            var searchTerm = selectedWorkshops[i].WorkshopId;
            if (workshops[j].WorkshopId === searchTerm) {
                workshops = workshops.slice(j);
            }
        }
        selectedWorkshops = selectedWorkshops.slice(i);
    }
};
addRemoveWorkshops();
addRemoveWorkshops=函数(){
var numberOfWorkshops=selectedWorkshops.length;
对于(var i=0;i
但是,该功能似乎无法正常工作。它似乎并没有删除正确的车间,它似乎只是将一个选定的车间添加到注册的车间。我做错了什么

下面是一个代码笔演示:

addRemoveWorkshops=function(){
var numberOfWorkshops=selectedWorkshops.length;
对于(var i=0;i

})

A
while
loop+A
for
one:

var workshops = [{
    name: 'apples',
    WorkshopId: '19'
}, {
    name: 'oranges',
    WorkshopId: '3b'
}, {
    name: 'pears',
    WorkshopId: 'x6'
}, {
    name: 'pineapples',
    WorkshopId: '55'
}, {
    name: 'watermelons',
    WorkshopId: '8v'
}];

var selectedWorkshops = [{
    name: 'oranges',
    WorkshopId: '3b'
}, {
    name: 'watermelons',
    WorkshopId: '8v'
}, {
    name: 'pears',
    WorkshopId: 'x6'
}];

var registeredWorkshops = [];
var numberOfWorkshops;

addRemoveWorkshops = function () {
    numberOfWorkshops = selectedWorkshops.length;
    // A single while statment is enough and lighter
    while (selectedWorkshops.length) {
        var removedWorkshop;
        numberOfWorkshops = registeredWorkshops.push(selectedWorkshops[0]);
        for (var i = 0; i < workshops.length; i++)
        if (workshops[i].WorkshopId == selectedWorkshops[0].WorkshopId) {
            workshops.splice(i, 1);
            break;
        }
        selectedWorkshops.splice(0, 1);
    }
};
addRemoveWorkshops();

// Better for viewing the content (in firefox I have just "Object") : 
console.log("workshops : ");
for (var i = 0; i < workshops.length; i++)
console.log('- ' + workshops[i].name);

console.log("selectedWorkshops : ");
for (var i = 0; i < selectedWorkshops.length; i++)
console.log('- ' + selectedWorkshops[i].name);

console.log("registeredWorkshops : ");
for (var i = 0; i < registeredWorkshops.length; i++)
console.log('- ' + registeredWorkshops[i].name);
var=[{
名字:'苹果',
WorkshopId:'19'
}, {
名称:“橙子”,
工作区ID:'3b'
}, {
名称:‘梨’,
工作区ID:'x6'
}, {
名称:'菠萝',
工作区ID:'55'
}, {
名称:“西瓜”,
工作区ID:“8v”
}];
var selectedWorkshops=[{
名称:“橙子”,
工作区ID:'3b'
}, {
名称:“西瓜”,
工作区ID:“8v”
}, {
名称:‘梨’,
工作区ID:'x6'
}];
var registeredWorkshops=[];
var工作坊;
addRemoveWorkshops=函数(){
NumberOfWorkshop=所选Workshop.length;
//一段时间就够了,而且更轻
while(selectedWorkshops.length){
var远程培训工作坊;
numberOfWorkshops=注册的车间。推送(selectedWorkshops[0]);
对于(变量i=0;i<0.length;i++)
if(车间[i].WorkshopId==selectedWorkshops[0].WorkshopId){
车间.拼接(i,1);
打破
}
所选车间。拼接(0,1);
}
};
addRemoveWorkshops();
//更好地查看内容(在firefox中,我只有“对象”):
控制台日志(“工作坊:”);
对于(变量i=0;i<0.length;i++)
console.log('-'+workshops[i].name);
console.log(“selectedWorkshops:”);
对于(变量i=0;i
我认为稍微重新思考一下您的数据结构会更容易。如果您选择上面的强制解决方案,您将面临在多个列表中出现重复值的风险

已注册的
选定的
属性添加到车间对象是否更容易

var workshops = [
  {
    name: 'apples',
    WorkshopId: '19',
    registered: true,
    selected: false
  },
  {
    name: 'oranges',
    WorkshopId: '3b',
    selected: true,
    registered: false
  },
  // ...
];
然后,如果您需要能够获得所有注册研讨会的列表,您可以使用过滤器创建它

// helper function for filtering based
// on a given property
function property(name) {
  return function(object) {
    return object[name];
  }
}

var registered = workshops.filter(property('registered'));
var selected = workshops.filter(property('selected'));
要选择车间,只需将select属性更改为true:

workshops[3].selected = true;
然后,您可以编写原始函数来注册选择的所有研讨会,如下所示:

function registration(workshops) {
  workshops.forEach(function(workshop) {
    if(workshop.selected) {
      workshop.registered = true;
      workshop.selected = false;
    }
  });
}
function registration(workshops, selected, registered) {

  // add the selected workshops to registered
  selected.forEach(function(workshop) {
    registered.push(workshop);
  });

  // remove them from the other lists
  registered.forEach(function(workshop) {
    removeWorkshop(selected, workshop);
    removeWorkshop(workshops, workshop);
  });

}

function removeWorkshop(list, workshop) {
  var index = list.indexOf(workshop);

  if(index >= 0) {
    list.splice(index, 1);
  }
}

如果无法向对象添加其他属性(根据),则我将如下处理:

function registration(workshops) {
  workshops.forEach(function(workshop) {
    if(workshop.selected) {
      workshop.registered = true;
      workshop.selected = false;
    }
  });
}
function registration(workshops, selected, registered) {

  // add the selected workshops to registered
  selected.forEach(function(workshop) {
    registered.push(workshop);
  });

  // remove them from the other lists
  registered.forEach(function(workshop) {
    removeWorkshop(selected, workshop);
    removeWorkshop(workshops, workshop);
  });

}

function removeWorkshop(list, workshop) {
  var index = list.indexOf(workshop);

  if(index >= 0) {
    list.splice(index, 1);
  }
}
该函数期望每个数组都作为参数传入,并在适当的位置修改它们。如果在嵌套之前将循环移出到函数中,事情总是变得更清楚、更容易测试

这里应该没有理由不使用
indexOf
方法,因为这样可以避免编写额外的循环。但是,如果出于某种原因需要使用
WorkshopId
属性在列表中查找项目,则可以创建另一个帮助器方法来完成此操作

function findWorkshop(list, workshop) {
  for(var i = 0; i < list.length; i++) {
    if(list[i].WorkshopId === workshop.WorkshopID) {
      return i;
    }
  }

  return -1;
}

我认为当I或j值为时,您不能调用array.slice(I)或array.slice(j)zero@TheGuest可以,但它只返回一个空数组。@DanPrince我的意思是在这种情况下,不幸的是,在这种情况下,我不能这样做(尽管这肯定会更容易)。不过谢谢你。回答得好。当我运行此操作时,它成功删除了“selectedWorkshops”数组中的对象。但是,它没有成功地从“车间阵列”中删除正确的项目。相反,剩余的数组项是“苹果”和“橙子”,尽管在注册的数组中也可以找到橙子。如果可以,请编辑您的问题以解决此问题。除了它不起作用之外,它是最接近我问题的直接答案。我的错,明白了。。。indexOf使用的是严格的等式。来自车间和选定车间的橙子不是同一个对象,而是相同的对象。对不起,这个错误。我正在写一个快速修复方法。@saestris:更新。不管怎样,正如@Dan Prince所说的,最好改进您的数据结构:如果您不能遵循他的建议,我建议您这样做:而不是存储clon