Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/477.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在数组中循环并移除项,而不中断循环_Javascript_Loops - Fatal编程技术网

Javascript 在数组中循环并移除项,而不中断循环

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.

我有以下for循环,当我使用
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;
          })