Javascript 在数组中循环并移除项,而不中断循环
我有以下for循环,当我使用Javascript 在数组中循环并移除项,而不中断循环,javascript,loops,Javascript,Loops,我有以下for循环,当我使用splice()删除一个项目时,我会得到“秒”是未定义的。我可以检查它是否未定义,但我觉得可能有一种更优雅的方法来实现这一点。我们的愿望是简单地删除一个项目并继续下去 for (i = 0, len = Auction.auctions.length; i < len; i++) { auction = Auction.auctions[i]; Auction.auctions[i]['seconds'] --; if (auction.
splice()
删除一个项目时,我会得到“秒”是未定义的。我可以检查它是否未定义,但我觉得可能有一种更优雅的方法来实现这一点。我们的愿望是简单地删除一个项目并继续下去
for (i = 0, len = Auction.auctions.length; i < len; i++) {
auction = Auction.auctions[i];
Auction.auctions[i]['seconds'] --;
if (auction.seconds < 0) {
Auction.auctions.splice(i, 1);
}
}
for(i=0,len=Auction.auctions.length;i
每次通过循环而不是在开始时重新计算长度,例如:
for (i = 0; i < Auction.auctions.length; i++) {
auction = Auction.auctions[i];
Auction.auctions[i]['seconds'] --;
if (auction.seconds < 0) {
Auction.auctions.splice(i, 1);
i--; //decrement
}
}
for(i=0;i
这样你就不会越界了
编辑:在if语句中添加减量。当您执行
.splice()
时,数组将被重新索引,这意味着您将在删除索引时跳过索引,并且缓存的.length
已过时
要修复它,您需要在.splice()
之后减小i
,或者简单地反向迭代
var i = Auction.auctions.length
while (i--) {
...
if (...) {
Auction.auctions.splice(i, 1);
}
}
这样,重新索引不会影响迭代中的下一项,因为索引只影响从当前点到数组末尾的项,迭代中的下一项低于当前点。虽然您的问题是从迭代的数组中删除元素,而不是高效地删除元素(除了一些其他处理),但我认为如果在类似情况下,应该重新考虑 这种方法的算法复杂性是
O(n^2)
,因为拼接函数和for循环都在数组中迭代(拼接函数在最坏的情况下移动数组的所有元素)。相反,您可以将所需的元素推送到新数组中,然后将该数组分配给所需的变量(该变量刚刚被迭代)
这是一个相当普遍的问题。解决方案是向后循环:
for (var i = Auction.auctions.length - 1; i >= 0; i--) {
Auction.auctions[i].seconds--;
if (Auction.auctions[i].seconds < 0) {
Auction.auctions.splice(i, 1);
}
}
for(var i=Auction.auctions.length-1;i>=0;i--){
拍卖.拍卖[i].秒--;
if(Auction.auctions[i].seconds<0){
拍卖.拍卖.拼接(i,1);
}
}
如果从末尾弹出它们并不重要,因为索引将在返回时保留。在循环时尝试将数组中继到新数组中:
var auctions = Auction.auctions;
var auctionIndex;
var auction;
var newAuctions = [];
for (
auctionIndex = 0;
auctionIndex < Auction.auctions.length;
auctionIndex++) {
auction = auctions[auctionIndex];
if (auction.seconds >= 0) {
newAuctions.push(
auction);
}
}
Auction.auctions = newAuctions;
var auctions=Auction.auctions;
var拍卖指数;
var拍卖;
var newAuctions=[];
为了(
拍卖指数=0;
auctionIndex=0){
推(
拍卖);
}
}
Auction.auctions=newAuctions;
这里是正确使用接头的另一个示例。此示例将从“数组”中删除“属性”
for (var i = array.length; i--;) {
if (array[i] === 'attribute') {
array.splice(i, 1);
}
}
另一个简单的解决方案是一次性消化数组元素:
while(Auction.auctions.length){
// From first to last...
var auction = Auction.auctions.shift();
// From last to first...
var auction = Auction.auctions.pop();
// Do stuff with auction
}
for(i=0,len=Auction.auctions.length;i
如果您使用的是ES6+,您只需查看并使用即可-为什么不直接使用数组.过滤器
方法
Auction.auctions = Auction.auctions.filter((auction) => {
auction['seconds'] --;
return (auction.seconds > 0)
})
请注意,在过滤器迭代过程中修改数组元素只适用于对象,而不适用于原始值数组。在这个线程中已经有很多精彩的答案。然而,当我试图在ES5上下文中解决“从数组中删除第n个元素”时,我想分享我的经验 JavaScript数组有不同的方法从开始或结束添加/删除元素。这些是:
arr.push(ele) - To add element(s) at the end of the array
arr.unshift(ele) - To add element(s) at the beginning of the array
arr.pop() - To remove last element from the array
arr.shift() - To remove first element from the array
基本上,上述方法都不能直接用于从数组中删除第n个元素
值得注意的一个事实是,这与java迭代器的相反
使用它可以删除集合的第n个元素
在迭代时
这基本上只剩下一种数组方法array.splice
来执行第n个元素的删除(也可以使用这些方法执行其他操作,但在这个问题的上下文中,我将重点介绍元素的删除):
以下是从原始答案复制的代码(带注释):
var arr=[“一”、“二”、“三”、“四”];
var i=阵列长度//将计数器初始化为数组长度
while(i--)//减量计数器,否则将运行IndexOutBounds异常
{
如果(arr[i]=“四”| arr[i]=“二”){
//拼接修改原始阵列
arr.splice(i,1);//永远不会遇到IndexOutBounds异常
console.log(“元素已移除。arr:”);
}否则{
日志(“元素未删除。arr:”);
}
控制台日志(arr);
}
这是一个简单线性时间问题的简单线性时间解决方案
当我运行这个代码段时,n=100万,每次调用filterPlace()都需要.013到.016秒。一个二次解决方案(例如,被接受的答案)将需要一百万倍的时间,或者说
//从数组中删除所有项,以便!条件(项目)。
函数过滤器位置(数组、条件){
var-iOut=0;
对于(var i=0;iwhile(Auction.auctions.length){
// From first to last...
var auction = Auction.auctions.shift();
// From last to first...
var auction = Auction.auctions.pop();
// Do stuff with auction
}
for (i = 0, len = Auction.auctions.length; i < len; i++) {
auction = Auction.auctions[i];
Auction.auctions[i]['seconds'] --;
if (auction.seconds < 0) {
Auction.auctions.splice(i, 1);
i--;
len--;
}
}
Auction.auctions = Auction.auctions.filter((auction) => {
auction['seconds'] --;
return (auction.seconds > 0)
})
arr.push(ele) - To add element(s) at the end of the array
arr.unshift(ele) - To add element(s) at the beginning of the array
arr.pop() - To remove last element from the array
arr.shift() - To remove first element from the array
Array.splice(index,1) - removes the element at the index
(Example ONE)
// Remove from Listing the Items Checked in Checkbox for Delete
let temp_products_images = store.state.c_products.products_images
if (temp_products_images != null) {
for (var l = temp_products_images.length; l--;) {
// 'mark' is the checkbox field
if (temp_products_images[l].mark == true) {
store.state.c_products.products_images.splice(l,1); // THIS WORKS
// this.$delete(store.state.c_products.products_images,l); // THIS ALSO WORKS
}
}
}
(Example TWO)
// Remove from Listing the Items Checked in Checkbox for Delete
let temp_products_images = store.state.c_products.products_images
if (temp_products_images != null) {
let l = temp_products_images.length
while (l--)
{
// 'mark' is the checkbox field
if (temp_products_images[l].mark == true) {
store.state.c_products.products_images.splice(l,1); // THIS WORKS
// this.$delete(store.state.c_products.products_images,l); // THIS ALSO WORKS
}
}
}
oldJson=[{firstName:'s1',lastName:'v1'},
{firstName:'s2',lastName:'v2'},
{firstName:'s3',lastName:'v3'}]
newJson = oldJson.map(({...ele}) => {
delete ele.firstName;
return ele;
})