我有以下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(||)运算符吗?如果没有,使用多个条件从数组中删除元素的正确方法是什么?
这个问题,我一直在摸不着头几个小时,但也许我错过了什么。
答案 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;
答案 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
数组中删除i
(i
本身);当前元素恰好是包含data
和eee
的对象。如果必须,请运行您的循环,计算iii
以向自己证明i
和data[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
更清晰,并会根据条件过滤您的列表。