2011-10-27 40 views
7

Làm thế nào chính xác công việc của Javascript array.reverse()? Nó có đi qua và trao đổi mọi phần tử của mảng không? Nếu vậy, có phải mất O (n) để hoán đổi một mảng có kích thước n không?Mảng của Javascript Đảo ngược

Tôi đoán lý do tôi hỏi là vì tôi đã tự hỏi nếu array.reverse() là giống như:

for(var i = 0; i < a.length/2; i++) { 
    var holder = a[i]; 
    a[i] = a[a.length - 1 - i]; 
    a[a.length - 1 - i] = holder; 
} 

LƯU Ý: Sorry nếu mã javascript tôi đăng là không chính xác, đó là khá muộn ngay bây giờ.

EDIT: Cố định a.length đến a.length/2.

+2

Đó là không chính xác bởi vì bằng cách vượt qua mảng đầy đủ, bạn sẽ trao đổi tất cả các phần tử hai lần và trở về mảng ban đầu. Sử dụng 'a.length/2' (phân chia số nguyên của a.length và 2) – xanatos

Trả lời

6

Để biết chi tiết đầy đủ về cách hoạt động, read the relevant section of the spec. Dưới đây là các thuật toán:

  1. Hãy O là kết quả của gọi ToObject đi qua các giá trị này như là đối số.

    1. Cho lenVal là kết quả của việc gọi phương thức bên trong [[Get]] của O với tham số "độ dài".
    2. Hãy để len ​​là ToUint32 (lenVal).
    3. Cho sàn giữa (len/2).
    4. Letlower được 0.
    5. Lặp lại, trong khi thấp hơn ≠ giữa

      1. Hãy thượng được len-thấp hơn -1.
      2. Cho phép chữ viết hoa ở trên (trên).
      3. Đặt lowP thành ToString (thấp hơn).
      4. Để giá trị thấp hơn là kết quả của việc gọi phương thức bên trong [[Nhận]] của O với đối số lowerP.
      5. Để giá trị cao hơn là kết quả của việc gọi phương thức bên trong [[Nhận]] của O với đối số upperP.
      6. Cho phép người thấp hơn là kết quả của việc gọi phương thức nội bộ [[HasProperty]] của O với đối số lowerP.
      7. Cho phép người dùng cấp cao là kết quả của việc gọi phương thức nội bộ [[HasProperty]] của O với đối số upperP.
      8. Nếu lowerExists là đúng và upperExists là đúng, sau đó

      9. Gọi [[Đặt]] phương pháp nội bộ của O với các đối số lowerP, upperValue, và đúng sự thật.

      10. Gọi phương thức nội bộ [[Đặt]] của O với đối số upperP, lowerValue và true.
      11. Khác nếu lowerExists là false và upperExists là true, sau đó
      12. Gọi phương thức bên trong [[Đặt]] của O với đối số lowerP, upperValue và true.
      13. Gọi phương thức bên trong [[Xóa]] của O, với đối số là upperP và true.
      14. Khác nếu lowerExists là true và upperExists là false, sau đó
      15. Gọi phương thức bên trong [[Xóa]] của O, với đối số lowerP và true.
      16. Gọi phương thức bên trong [[Đặt]] của O với đối số upperP, lowerValue và true.
      17. Khác, cả lowerExists và upperExists là false
      18. Không cần thực hiện hành động nào.
      19. Tăng thấp hơn 1.
    6. Trả lại O.
2

Thuật toán thực tế là gần như tương tự với những gì mà bạn chỉ định. Chỉ cần thay đổi vòng lặp for của bạn để chỉ lặp lại tối đa a.length/2 và nó sẽ tương tự như những gì Array.reverse sẽ làm. Tôi đang bỏ qua các chi tiết bên trong ở đây vì mục đích đơn giản. Vì vậy, nó sẽ là

for(var i = 0; i < a.length/2; i++) { 
    var holder = a[i]; 
    a[i] = a[a.length - 1 - i]; 
    a[a.length - 1 - i] = holder; 
}