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

时间:2015-04-14 15:39:06

标签: javascript arrays

我正在尝试构建一个3层函数: 首先,一个数组列出了可用的研讨会(数组被称为'研讨会')。 其次,另一个阵列列出了用户选择的研讨会(该阵列被称为' selectedWorkshops')。 第三,我有一个名为' registeredWorkshops'的最终阵列。

当我的功能运行时,我想要在选定的工作场所内的对象'要添加到' registeredWorkshops',然后我想删除所选工作坊内的任何对象'来自两个选定的工作坊'以及来自' workshop'的任何匹配元素。因此,这些对象过去常常存在于选定的工作场所和#39;和#'工作坊'现在他们只存在于注册工作坊'。

这是我到目前为止所得到的:

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

但是,该功能似乎无法正常工作。它似乎没有删除正确的研讨会,它似乎只是将一个选定的工作坊添加到注册的工作坊。我做错了什么?

这是一个codepen演示:http://codepen.io/trueScript/pen/GgVWMx

4 个答案:

答案 0 :(得分:2)

我认为稍微重新考虑一下您的数据结构会更容易。如果您使用上面的命令性解决方案,则可能会遇到在多个列表中以重复值结束的风险。

registeredselected属性添加到研讨会对象会不会更容易?

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

答案 1 :(得分:2)

如果无法向对象添加其他属性(根据my other answer),那么我就像这样处理它:

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

然后你只需修改removeWorkshop函数来反映这一点。

function removeWorkshop(list, workshop) {
  var index = findWorkshop(list, workshop);
  list.splice(index, 1);
}

答案 2 :(得分:1)

while循环+ for一个:

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

答案 3 :(得分:0)

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.splice(j,1);
        }
    }
    selectedWorkshops = selectedWorkshops.splice(i,1);
}

};