For Loop on Lua


86

Bài tập của tôi là làm thế nào để thực hiện một vòng lặp for. Tôi đã tìm ra nó về mặt con số nhưng không thể hình dung nó về mặt tên gọi. Tôi muốn tạo một vòng lặp for chạy xuống một danh sách các tên. Sau đây là những gì tôi có cho đến nay:

names = {'John', 'Joe', 'Steve'}
for names = 1, 3 do
  print (names)
end

Tôi đã thử một số cách khác nhưng nó không hoạt động, thiết bị đầu cuối luôn chỉ liệt kê 1, 2, 3 ... Tôi đang làm gì sai?

Câu trả lời:


203

Vấn đề của bạn rất đơn giản:

names = {'John', 'Joe', 'Steve'}
for names = 1, 3 do
  print (names)
end

Đoạn mã này đầu tiên khai báo một biến toàn cục được gọi names. Sau đó, bạn bắt đầu một vòng lặp for. Vòng lặp for khai báo một địa phương biến mà chỉ xảy ra được gọi là namesquá; thực tế là một biến đã được xác định trước đó nameslà hoàn toàn không liên quan. Bất kỳ việc sử dụng nào namesbên trong vòng lặp for sẽ tham chiếu đến vòng lặp cục bộ , không phải vòng lặp toàn cục.

Vòng lặp for nói rằng phần bên trong của vòng lặp sẽ được gọi với names = 1, sau đó names = 2, và cuối cùng names = 3. Vòng lặp for khai báo một bộ đếm mà đếm từ số đầu tiên đến cuối cùng, và nó sẽ gọi mã bên trong một lần cho mỗi giá trị nó đếm.

Những gì bạn thực sự muốn là một cái gì đó như thế này:

names = {'John', 'Joe', 'Steve'}
for nameCount = 1, 3 do
  print (names[nameCount])
end

Cú pháp [] là cách bạn truy cập các thành viên của bảng Lua. Bảng Lua ánh xạ "khóa" thành "giá trị". Mảng của bạn tự động tạo các khóa kiểu số nguyên, các khóa này sẽ tăng lên. Vì vậy, khóa được liên kết với "Joe" trong bảng là 2 (các chỉ số Lua luôn bắt đầu từ 1).

Do đó, bạn cần một vòng lặp for đếm từ 1 đến 3, mà bạn nhận được. Bạn sử dụng biến đếm để truy cập phần tử từ bảng.

Tuy nhiên, điều này có một lỗ hổng. Điều gì xảy ra nếu bạn xóa một trong các phần tử khỏi danh sách?

names = {'John', 'Joe'}
for nameCount = 1, 3 do
  print (names[nameCount])
end

Bây giờ, chúng tôi nhận được John Joe nil, vì cố gắng truy cập các giá trị từ một bảng không tồn tại dẫn đến kết quả nil. Để tránh điều này, chúng ta cần đếm từ 1 đến chiều dài của bảng:

names = {'John', 'Joe'}
for nameCount = 1, #names do
  print (names[nameCount])
end

#toán tử độ dài. Nó hoạt động trên các bảng và chuỗi, trả về độ dài của một trong hai. Bây giờ, bất kể lớn hay nhỏ names, điều này sẽ luôn hoạt động.

Tuy nhiên, có một cách thuận tiện hơn để lặp qua một mảng các mục:

names = {'John', 'Joe', 'Steve'}
for i, name in ipairs(names) do
  print (name)
end

ipairslà một hàm tiêu chuẩn Lua lặp qua một danh sách. Kiểu forvòng lặp này, vòng lặp for vòng lặp, sử dụng loại chức năng trình vòng lặp này. Các igiá trị là chỉ số của các mục trong mảng. Các namegiá trị là giá trị tại chỉ mục đó. Vì vậy, về cơ bản nó làm rất nhiều việc cho bạn.


1
Vì vậy, đối với ipairs () hoạt động như foreach () trong các ngôn ngữ khác
boctulus

15
Câu trả lời tuyệt vời, tôi chỉ muốn nói thêm rằng trong ví dụ cuối cùng, nó khá thông thường để sử dụng _khi var không được sử dụng. ví dụnames = {'John', 'Joe', 'Steve'} for _, name in ipairs(names) do print (name) end
Fraser

19

Bằng cách đọc trực tuyến ( hướng dẫn về bảng ), có vẻ như các bảng hoạt động giống như mảng nên bạn đang tìm kiếm:

Way1

names = {'John', 'Joe', 'Steve'}
for i = 1,3 do print( names[i] ) end

Way2

names = {'John', 'Joe', 'Steve'}
for k,v in pairs(names) do print(v) end

Way1 sử dụng bảng index/key, trên bảng của bạn namesmỗi phần tử có một khóa bắt đầu từ 1, ví dụ:

names = {'John', 'Joe', 'Steve'}
print( names[1] ) -- prints John

Vì vậy, bạn chỉ cần thực hiện iđi từ 1 đến 3.

Thay vào đó, trên Way2, bạn chỉ định bảng bạn muốn chạy và gán một biến cho khóa và giá trị của nó, ví dụ:

names = {'John', 'Joe', myKey="myValue" }
for k,v in pairs(names) do print(k,v) end

in như sau:

1   John
2   Joe
myKey   myValue

6
Bạn đã đọc hướng dẫn bảng, nhưng bạn không thấy ipairs? Hoặc phần pairskhông phải trả lại các giá trị khóa theo bất kỳ thứ tự cụ thể nào?
Nicol Bolas

Tôi thực sự đã sử dụng ipairslúc đầu nhưng khi tôi thêm myKey="myValue"ví dụ cần pairscho phím không phải số, tôi cũng quyết định thay đổi phần còn lại pairs. Tôi xin lỗi nếu tôi bỏ qua rằng đơn đặt hàng không được đảm bảo với các cặp nhưng tôi đã để lại liên kết ngay tại đó cho anh ta đọc.
derp

1
names = {'John', 'Joe', 'Steve'}
for names = 1, 3 do
  print (names)
end
  1. Bạn đang xóa bảng của mình và thay thế nó bằng một int
  2. Bạn không lấy một giá trị từ bảng

Thử:

names = {'John','Joe','Steve'}
for i = 1,3 do
    print(names[i])
end

1
Phản đối: vui lòng cung cấp lý do hợp lệ cho việc phản đối. Mặc dù tôi nghĩ rằng câu trả lời là sai ở chỗ names(bộ đếm số nguyên) như được khai báo trong forphạm vi giới thiệu một biến cục bộ, làm bóng names(mảng bảng) như được khai báo trong phạm vi toàn cục.
Dejavu
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.