angular.forEach中的OR(||)运算符不起作用?

时间:2016-06-08 14:18:12

标签: javascript arrays angularjs

我有以下json数组,需要在某些条件下删除其中一些:

var data = [
             {data1: "aaa", data2: "bbb", data3: "ccc"},  // First
             {data1: "ddd", data2: "eee", data3: "fff"},  // Second
             {data1: "ggg", data2: "hhh", data3: "iii"},  // Third
             {data1: "jjj", data2: "eee", data3: "lll"}   // Fourth
           ];
angular.forEach(data, (item, i) => {
  if (item.data2 == 'eee' || item.data3 == 'iii') {
    data.splice(i, 1);
  }
});
console.log(data);

在上面的例子中,我需要删除第二个(data2有" eee"),第三个(data3有" iii"),第四个(data2是" eee& #34;)来自数据数组的对象。 但是,第三个对象没有拼接并保留在数据数组中。

我能以这种方式使用OR(||)运算符吗?如果没有,使用多个条件从数组中删除元素的正确方法是什么?

这个问题,我一直在摸不着头几个小时,但也许我错过了什么。

4 个答案:

答案 0 :(得分:1)

使用filter代替splice

splice与项目的索引有关,因此当您在循环中删除项目时,索引号将变为无效。



var data = [
             {data1: "aaa", data2: "bbb", data3: "ccc"},  // First
             {data1: "ddd", data2: "eee", data3: "fff"},  // Second
             {data1: "ggg", data2: "hhh", data3: "iii"},  // Third
             {data1: "jjj", data2: "eee", data3: "lll"}   // Fourth
           ];

function keepItemCondition(item) {
  return !(item.data2 == 'eee' || item.data3 == 'iii');
}

var filtered = data.filter(keepItemCondition);

console.log(filtered);

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

请改用过滤器, 使用拼接时,您需要更改要迭代的数组,这是一个不能否:

var data = [
             {data1: "aaa", data2: "bbb", data3: "ccc"},  // First
             {data1: "ddd", data2: "eee", data3: "fff"},  // Second
             {data1: "ggg", data2: "hhh", data3: "iii"},  // Third
             {data1: "jjj", data2: "eee", data3: "lll"}   // Fourth
           ];
var filtered = data.filter(function (element) {
    return element.data2 !== 'eee' && element.data3 !== 'iii';
});
console.log(filtered);

答案 2 :(得分:0)

在控制台中检查输出时,您会看到返回的是一个数组:

[Object, Object]

含有

[{'aaa', 'bbb', 'ccc'}, {'ggg', 'hhh', 'iii'}]

这告诉我们您的代码正在删除第2和第4个数组对象。作为证明,请注释掉foreach例程,以发现保留原始数组的完整性。

为什么呢?好吧,你的逻辑 OR(||)运算符按预期工作!

angular.forEach(data, (item, i) => {
  if (item.data2 == 'eee' || item.data3 == 'iii') {
    data.splice(i, 1);
  }
});

当检查当前对象中的对象项data2 == 'eee'data3 == 'iii'时,您的代码会说要拼接(,换句话说,删除)从{{开始的元素1}}并以i数组中的i结尾。这是通过你写data的事实表达的;如果您编写了类似splice(i, 1)的内容,您可以删除从splice(i, 3)开始到i结束的对象元素。另一种方法是说,&#34; i+2表示从索引splice(i, n)&#34;开始删除n元素。

因此,每次评估比较表达式时,您都要命令中的当前元素i i 元素从1数组中删除ii本身);当前元素恰好是包含dataeee对象。如果必须,请运行您的循环,计算iii以向自己证明idata[1]已被移除。

如果您在项目data[3]或项目data2 == eee时询问如何删除对象的特定项目,请考虑以下事项:

data3 == iii

返回:

var data = [ {data1: "aaa", data2: "bbb", data3: "ccc"}, // First {data1: "ddd", data2: "eee", data3: "fff"}, // Second {data1: "ggg", data2: "hhh", data3: "iii"}, // Third {data1: "jjj", data2: "eee", data3: "lll"} // Fourt ]; angular.forEach(data, (item, i) => { if (item.data2 == 'eee') { delete data[i].data2; } else if (item.data3 == 'iii') { delete data[i].data3; } }); console.log(data);

正在进行工作演示JSFiddle。虽然您的 OR(||)表达确实&#34;工作&#34;但它并不完全符合您的预期,只是因为[{'aaa', 'bbb', 'ccc'}, {'ddd', 'fff'}, {'ggg', 'hhh'}, {'jjj, 'lll'}]被用来删除一个对象而不是一个项目。因此,我们必须改变我们的逻辑。

答案 3 :(得分:0)

正如我评论你的代码不起作用,因为当循环遍历数组时,如果你删除一个项目,下一个项目将放在被删除的项目索引中,索引会增加一个,并且永远不会评估此项目。

var data = [
  {data1: "aaa", data2: "bbb", data3: "ccc"},  // First
  {data1: "ddd", data2: "eee", data3: "fff"},  // Second
  {data1: "ggg", data2: "hhh", data3: "iii"},  // Third
  {data1: "jjj", data2: "eee", data3: "lll"}   // Fourth
];

// Won't work
for(var i = 0; i < data.length; i++){
  var item = data [i];
  if (item.data2 == 'eee' || item.data3 == 'iii') {
    data.splice(i, 1);
  }
}
console.log(data);

一种解决方案是以反向模式循环。在这种情况下,删除项目不会影响下一个项目。

var data = [
  {data1: "aaa", data2: "bbb", data3: "ccc"},  // First
  {data1: "ddd", data2: "eee", data3: "fff"},  // Second
  {data1: "ggg", data2: "hhh", data3: "iii"},  // Third
  {data1: "jjj", data2: "eee", data3: "lll"}   // Fourth
];

for(var i = data.length -1; i >= 0; i--)
  if (data[i].data2 == 'eee' || data[i].data3 == 'iii')
    data.splice(i, 1);

console.log(data);

如果你想保持forEach循环风格,你可以自己做forEachReverse

Array.prototype.forEachReverse = function (callback){ 
  var arr = this;
  for(var i = arr.length -1; i >= 0; i--) 
  	callback(arr[i], i, arr);
};


var data = [
  {data1: "aaa", data2: "bbb", data3: "ccc"},  // First
  {data1: "ddd", data2: "eee", data3: "fff"},  // Second
  {data1: "ggg", data2: "hhh", data3: "iii"},  // Third
  {data1: "jjj", data2: "eee", data3: "lll"}   // Fourth
];

data.forEachReverse((item, i)=>{
  if (item.data2 == 'eee' || item.data3 == 'iii') {
    data.splice(i, 1);
  }
});

console.log(data);

正如其他答案所示,filter更清晰,并会根据条件过滤您的列表。