2013-06-26 73 views
7

Tôi tự hỏi nếu và một cách đáng tin cậy và/hoặc tiêu chuẩn của việc lặp lại một mảng có chiều dài đang thay đổi bên trong vòng lặp là gì. Tôi hỏi vì tôi sẽ chọn một phương pháp khác để thực hiện việc này mỗi lần tôi muốn làm điều đó, ví dụ:Lặp lại mảng khi loại bỏ các phần tử

for (var i = 0; i < myarray.length; i++) { 
    if (myarray[i] === 'something') { 
    myarray.splice(i, 1); 

    // *to avoid jumping over an element whose index was just shifted back to the current i 
    i--; 
    } 
} 

hay

var i = 0; 
while (myarray[i]) { 
    if (myarray[i] === 'something') { 
    myarray.splice(i, 1); 
    } else { 
    i++; 
    } 
} 

Đây là những cách tôi thấy mình làm điều này, nhưng tôi tò mò nếu có một cách tiếp cận tiêu chuẩn.

+0

Bạn đã kiểm tra này [http://stackoverflow.com/questions/9882284/looping-through-array-and- câu trả lời xóa-mục-không-phá-cho-vòng lặp]? –

+1

Bạn có thể giữ bước chuyển tiếp của bạn trong ví dụ đầu tiên và đặt bài viết của bạn giảm dần 'i' trực tiếp trong lệnh' .splice() ':' myarray.splice (i--, 1); ' –

Trả lời

22

tôi thấy đơn giản để lặp theo một hướng khác:

for (var i=myarray.length; i--;) { 
    if (myarray[i] === 'something') myarray.splice(i, 1); 
} 

Bằng cách này bạn không cần phải thay đổi thặng dư khi loại bỏ.

Nhiều nhà phát triển, đặc biệt là những người không xử lý ngôn ngữ giống như C trước JavaScript, thấy khó hiểu để giải quyết sự tinh tế của toán tử giảm dần. Vòng lặp tôi đã viết cũng có thể được viết là

for (var i=myarray.length-1; i>=0; i--) { 
+0

điều này thật tuyệt vời, cảm ơn bạn –

+0

+1 Tôi đã hỏi một câu hỏi tương tự trong buổi phỏng vấn hôm nay ;-) Phần tốt nhất là ngay cả khi tôi không nghĩ về giải pháp này –

+0

Điều này chắc chắn là cách được đề xuất để lặp qua bộ sưu tập sẽ bị xóa. Tôi làm điều này bằng bất kỳ ngôn ngữ nào. – jlafay

0

Tuy nhiên bạn chọn làm điều đó, bắt đầu ngược lại và đếm ngược đơn giản nhất. Nó cũng phụ thuộc vào mảng của bạn là thưa thớt và nếu bạn muốn cho nó vẫn còn thưa thớt. Dễ nhất là tạo cho mình một chức năng tái sử dụng và thư viện của riêng bạn. Bạn có thể làm điều này. Nếu bạn đặt compress thành true thì mảng của bạn sẽ trở thành mảng liên tục chứ không phải là mảng thưa thớt. Hàm này sẽ xóa tất cả các lần xuất hiện phù hợp của giá trị và sẽ trả về một mảng các phần tử đã xóa.

Javascript

function is(x, y) { 
    if (x === y) { 
     if (x === 0) { 
      return 1/x === 1/y; 
     } 

     return true; 
    } 

    var x1 = x, 
     y1 = y; 

    return x !== x1 && y !== y1; 
} 

function removeMatching(array, value /*, compress (default = false)*/) { 
    var removed = [], 
     compress = arguments[2], 
     index, 
     temp, 
     length; 

    if (typeof compress !== "boolean") { 
     compress = false; 
    } 

    if (compress) { 
     temp = []; 
     length = array.length; 
     index = 0; 
     while (index < length) { 
      if (array.hasOwnProperty(index)) { 
       temp.push(array[index]); 
      } 

      index += 1; 
     } 
    } else { 
     temp = array; 
    } 

    index = 0; 
    length = temp.length; 
    while (index < length) { 
     if (temp.hasOwnProperty(index) && is(temp[index], value)) { 
      if (compress) { 
       removed.push(temp.splice(index, 1)[0]); 
      } else { 
       removed.push(temp[index]); 
       delete temp[index]; 
      } 
     } 

     index += 1; 
    } 

    if (compress) { 
     array.length = 0; 
     index = 0; 
     length = temp.length; 
     while (index < length) { 
      if (temp.hasOwnProperty(index)) { 
       array.push(temp[index]); 
      } 

      index += 1; 
     } 
    } 

    return removed; 
} 

var test = []; 

test[1] = 1; 
test[50] = 2; 
test[100] = NaN; 
test[101] = NaN; 
test[102] = NaN; 
test[200] = null; 
test[300] = undefined; 
test[400] = Infinity; 
test[450] = NaN; 
test[500] = -Infinity; 
test[1000] = 3; 

console.log(test); 
console.log(removeMatching(test, NaN)); 
console.log(test); 
console.log(removeMatching(test, Infinity, true)); 
console.log(test); 

Output

[1: 1, 50: 2, 100: NaN, 101: NaN, 102: NaN, 200: null, 300: undefined, 400: Infinity, 450: NaN, 500: -Infinity, 1000: 3] 
[NaN, NaN, NaN, NaN] 
[1: 1, 50: 2, 200: null, 300: undefined, 400: Infinity, 500: -Infinity, 1000: 3] 
[Infinity] 
[1, 2, null, undefined, -Infinity, 3] 

On jsfiddle

Các vấn đề liên quan