Untuk Loop di Lua

87

Tugas saya adalah bagaimana melakukan loop for. Saya telah mengetahuinya dari segi angka tetapi tidak dapat mengetahuinya dari segi nama. Saya ingin membuat perulangan for yang menjalankan daftar nama. Berikut ini yang saya miliki sejauh ini:

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

Saya telah mencoba beberapa hal lain tetapi tidak berhasil, terminal selalu hanya mencantumkan 1, 2, 3 ... Apa yang saya lakukan salah?

SamYoungNY
sumber

Jawaban:

204

Masalah Anda sederhana:

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

Kode ini pertama-tama mendeklarasikan variabel global yang dipanggil names. Kemudian, Anda memulai pengulangan for. Perulangan for mendeklarasikan variabel lokal yang kebetulan dipanggil namesjuga; fakta bahwa variabel sebelumnya telah didefinisikan dengan namessama sekali tidak relevan. Setiap penggunaan namesdi dalam for loop akan merujuk ke penggunaan lokal , bukan global.

Perulangan for mengatakan bahwa bagian dalam dari perulangan akan dipanggil dengan names = 1, kemudian names = 2, dan akhirnya names = 3. Perulangan for mendeklarasikan penghitung yang menghitung dari angka pertama hingga terakhir, dan akan memanggil kode dalam satu kali untuk setiap nilai yang dihitung.

Apa yang sebenarnya Anda inginkan adalah sesuatu seperti ini:

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

Sintaks [] adalah bagaimana Anda mengakses anggota tabel Lua. Tabel Lua memetakan "kunci" ke "nilai". Array Anda secara otomatis membuat kunci tipe integer, yang meningkat. Jadi kunci yang terkait dengan "Joe" dalam tabel adalah 2 (indeks Lua selalu dimulai dari 1).

Oleh karena itu, Anda memerlukan loop for yang menghitung dari 1 hingga 3, yang Anda dapatkan. Anda menggunakan variabel count untuk mengakses elemen dari tabel.

Namun, ini memiliki kekurangan. Apa yang terjadi jika Anda menghapus salah satu elemen dari daftar?

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

Sekarang, kita mengerti John Joe nil, karena mencoba mengakses nilai dari tabel yang tidak ada hasilnya nil. Untuk mencegahnya, kita perlu menghitung dari 1 sampai panjang meja:

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

Ini #adalah operator panjang. Ini berfungsi pada tabel dan string, mengembalikan panjang keduanya. Sekarang, tidak peduli seberapa besar atau kecilnya names, ini akan selalu berhasil.

Namun, ada cara yang lebih mudah untuk melakukan iterasi melalui berbagai item:

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

ipairsadalah fungsi standar Lua yang melakukan iterasi pada daftar. Gaya forpengulangan ini, pengulangan untuk pengulangan, menggunakan jenis fungsi iterator. The inilai adalah indeks entri dalam array. The namenilai adalah nilai pada indeks itu. Jadi pada dasarnya itu melakukan banyak pekerjaan kasar untuk Anda.

Nicol Bolas
sumber
1
Jadi, untuk dengan ipairs () berfungsi sebagai foreach () dalam bahasa lain
boctulus
15
Jawaban yang bagus, saya hanya akan menambahkan bahwa dalam contoh terakhir ini cukup lazim digunakan _ketika var tidak digunakan. misalnyanames = {'John', 'Joe', 'Steve'} for _, name in ipairs(names) do print (name) end
Fraser
19

Dengan membaca online ( tutorial tabel ) tampaknya tabel berperilaku seperti array sehingga Anda mencari:

Cara1

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

Cara2

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

Way1 menggunakan tabel index/key, di tabel Anda namessetiap elemen memiliki kunci mulai dari 1, misalnya:

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

Jadi Anda hanya membuat ipergi dari 1 ke 3.

Pada Way2, Anda menentukan tabel apa yang ingin Anda jalankan dan menetapkan variabel untuk kunci dan nilainya misalnya:

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

mencetak yang berikut ini:

1   John
2   Joe
myKey   myValue
derp
sumber
6
Anda membaca tutorial tabel, tetapi Anda tidak melihat ipairs? Atau bagian di mana pairstidak harus mengembalikan nilai kunci dalam urutan tertentu?
Nicol Bolas
Saya sebenarnya menggunakan ipairspada awalnya tetapi ketika saya menambahkan myKey="myValue"contoh yang membutuhkan pairskunci non-numerik, saya memutuskan untuk mengubah sisanya pairsjuga. Saya minta maaf jika saya menghilangkan bahwa pesanan tidak dijamin dengan pasangan tetapi saya meninggalkan tautan di sana untuk dia baca.
derp
1
names = {'John', 'Joe', 'Steve'}
for names = 1, 3 do
  print (names)
end
  1. Anda menghapus tabel Anda dan menggantinya dengan int
  2. Anda tidak menarik nilai dari tabel

Mencoba:

names = {'John','Joe','Steve'}
for i = 1,3 do
    print(names[i])
end
Elliot
sumber
1
Downvoters: berikan alasan yang valid untuk downvoting. Meskipun saya pikir jawabannya menyesatkan karena names(penghitung integer) seperti yang dideklarasikan dalam forlingkup memperkenalkan variabel lokal, yang membayangi names(array tabel) seperti yang dideklarasikan dalam lingkup global.
Dejavu