Dalam lua 5.1, Anda dapat mengulang karakter string ini dengan beberapa cara.
Loop dasarnya adalah:
untuk i = 1, #str do
lokal c = str: sub (i, i)
- melakukan sesuatu dengan c
akhir
Tetapi mungkin lebih efisien menggunakan pola dengan string.gmatch()
untuk mendapatkan iterator atas karakter:
untuk c di str: gmatch "." melakukan
- melakukan sesuatu dengan c
akhir
Atau bahkan digunakan string.gsub()
untuk memanggil fungsi untuk setiap karakter:
str: gsub (".", function (c)
- melakukan sesuatu dengan c
akhir)
Dalam semua hal di atas, saya telah memanfaatkan fakta bahwa string
modul disetel sebagai metatabel untuk semua nilai string, sehingga fungsinya dapat disebut sebagai anggota menggunakan :
notasi. Saya juga menggunakan (baru 5.1, IIRC) #
untuk mendapatkan panjang string.
Jawaban terbaik untuk aplikasi Anda bergantung pada banyak faktor, dan tolok ukur adalah teman Anda jika kinerja itu penting.
Anda mungkin ingin mengevaluasi mengapa Anda perlu mengulang karakter, dan untuk melihat salah satu modul ekspresi reguler yang telah terikat ke Lua, atau untuk pendekatan modern melihat ke modul lpeg Roberto yang mengimplementasikan Parsing Expression Grammers untuk Lua.
Jika Anda menggunakan Lua 5, coba:
for i = 1, string.len(str) do print( string.sub(str, i, i) ) end
sumber
Bergantung pada tugas yang ada, ini mungkin lebih mudah digunakan
string.byte
. Ini juga merupakan cara tercepat karena menghindari pembuatan substring baru yang terjadi menjadi sangat mahal di Lua berkat hashing dari setiap string baru dan memeriksa apakah sudah dikenal. Anda dapat menghitung kode simbol yang Anda cari sebelumnya untukstring.byte
menjaga keterbacaan dan portabilitas.local str = "ab/cd/ef" local target = string.byte("/") for idx = 1, #str do if str:byte(idx) == target then print("Target found at:", idx) end end
sumber
Sudah ada banyak pendekatan yang baik dalam jawaban yang diberikan (di sini , di sini dan di sini ). Jika kecepatan adalah apa yang Anda terutama mencari, Anda pasti harus mempertimbangkan melakukan pekerjaan melalui Lua C API, yang banyak kali lebih cepat daripada kode Lua mentah. Saat bekerja dengan potongan yang dimuat sebelumnya (mis. Fungsi beban ), perbedaannya tidak terlalu besar, tetapi masih cukup besar.
Adapun solusi Lua murni , izinkan saya membagikan patokan kecil ini, yang telah saya buat. Ini mencakup setiap jawaban yang diberikan hingga tanggal ini dan menambahkan beberapa pengoptimalan. Namun, hal dasar yang perlu dipertimbangkan adalah:
Berapa kali Anda perlu mengulang karakter dalam string?
Ini kode lengkapnya:
-- Setup locals local str = "Hello World!" local attempts = 5000000 local reuses = 10 -- For the second part of benchmark: Table values are reused 10 times. Change this according to your needs. local x, c, elapsed, tbl -- "Localize" funcs to minimize lookup overhead local stringbyte, stringchar, stringsub, stringgsub, stringgmatch = string.byte, string.char, string.sub, string.gsub, string.gmatch print("-----------------------") print("Raw speed:") print("-----------------------") -- Version 1 - string.sub in loop x = os.clock() for j = 1, attempts do for i = 1, #str do c = stringsub(str, i) end end elapsed = os.clock() - x print(string.format("V1: elapsed time: %.3f", elapsed)) -- Version 2 - string.gmatch loop x = os.clock() for j = 1, attempts do for c in stringgmatch(str, ".") do end end elapsed = os.clock() - x print(string.format("V2: elapsed time: %.3f", elapsed)) -- Version 3 - string.gsub callback x = os.clock() for j = 1, attempts do stringgsub(str, ".", function(c) end) end elapsed = os.clock() - x print(string.format("V3: elapsed time: %.3f", elapsed)) -- For version 4 local str2table = function(str) local ret = {} for i = 1, #str do ret[i] = stringsub(str, i) -- Note: This is a lot faster than using table.insert end return ret end -- Version 4 - function str2table x = os.clock() for j = 1, attempts do tbl = str2table(str) for i = 1, #tbl do -- Note: This type of loop is a lot faster than "pairs" loop. c = tbl[i] end end elapsed = os.clock() - x print(string.format("V4: elapsed time: %.3f", elapsed)) -- Version 5 - string.byte x = os.clock() for j = 1, attempts do tbl = {stringbyte(str, 1, #str)} -- Note: This is about 15% faster than calling string.byte for every character. for i = 1, #tbl do c = tbl[i] -- Note: produces char codes instead of chars. end end elapsed = os.clock() - x print(string.format("V5: elapsed time: %.3f", elapsed)) -- Version 5b - string.byte + conversion back to chars x = os.clock() for j = 1, attempts do tbl = {stringbyte(str, 1, #str)} -- Note: This is about 15% faster than calling string.byte for every character. for i = 1, #tbl do c = stringchar(tbl[i]) end end elapsed = os.clock() - x print(string.format("V5b: elapsed time: %.3f", elapsed)) print("-----------------------") print("Creating cache table ("..reuses.." reuses):") print("-----------------------") -- Version 1 - string.sub in loop x = os.clock() for k = 1, attempts do tbl = {} for i = 1, #str do tbl[i] = stringsub(str, i) -- Note: This is a lot faster than using table.insert end for j = 1, reuses do for i = 1, #tbl do c = tbl[i] end end end elapsed = os.clock() - x print(string.format("V1: elapsed time: %.3f", elapsed)) -- Version 2 - string.gmatch loop x = os.clock() for k = 1, attempts do tbl = {} local tblc = 1 -- Note: This is faster than table.insert for c in stringgmatch(str, ".") do tbl[tblc] = c tblc = tblc + 1 end for j = 1, reuses do for i = 1, #tbl do c = tbl[i] end end end elapsed = os.clock() - x print(string.format("V2: elapsed time: %.3f", elapsed)) -- Version 3 - string.gsub callback x = os.clock() for k = 1, attempts do tbl = {} local tblc = 1 -- Note: This is faster than table.insert stringgsub(str, ".", function(c) tbl[tblc] = c tblc = tblc + 1 end) for j = 1, reuses do for i = 1, #tbl do c = tbl[i] end end end elapsed = os.clock() - x print(string.format("V3: elapsed time: %.3f", elapsed)) -- Version 4 - str2table func before loop x = os.clock() for k = 1, attempts do tbl = str2table(str) for j = 1, reuses do for i = 1, #tbl do -- Note: This type of loop is a lot faster than "pairs" loop. c = tbl[i] end end end elapsed = os.clock() - x print(string.format("V4: elapsed time: %.3f", elapsed)) -- Version 5 - string.byte to create table x = os.clock() for k = 1, attempts do tbl = {stringbyte(str,1,#str)} for j = 1, reuses do for i = 1, #tbl do c = tbl[i] end end end elapsed = os.clock() - x print(string.format("V5: elapsed time: %.3f", elapsed)) -- Version 5b - string.byte to create table + string.char loop to convert bytes to chars x = os.clock() for k = 1, attempts do tbl = {stringbyte(str, 1, #str)} for i = 1, #tbl do tbl[i] = stringchar(tbl[i]) end for j = 1, reuses do for i = 1, #tbl do c = tbl[i] end end end elapsed = os.clock() - x print(string.format("V5b: elapsed time: %.3f", elapsed))
Contoh keluaran (Lua 5.3.4, Windows) :
----------------------- Raw speed: ----------------------- V1: elapsed time: 3.713 V2: elapsed time: 5.089 V3: elapsed time: 5.222 V4: elapsed time: 4.066 V5: elapsed time: 2.627 V5b: elapsed time: 3.627 ----------------------- Creating cache table (10 reuses): ----------------------- V1: elapsed time: 20.381 V2: elapsed time: 23.913 V3: elapsed time: 25.221 V4: elapsed time: 20.551 V5: elapsed time: 13.473 V5b: elapsed time: 18.046
Hasil:
Dalam kasus saya,
string.byte
danstring.sub
tercepat dalam hal kecepatan mentah. Saat menggunakan tabel cache dan menggunakannya kembali 10 kali per loop,string.byte
versinya adalah yang tercepat bahkan saat mengonversi kode karakter kembali ke karakter (yang tidak selalu diperlukan dan bergantung pada penggunaan).Seperti yang mungkin Anda perhatikan, saya telah membuat beberapa asumsi berdasarkan tolok ukur saya sebelumnya dan menerapkannya ke kode:
tbl[idx] = value
daripadatable.insert(tbl, value)
.for i = 1, #tbl
sedikit lebih cepat darifor k, v in pairs(tbl)
.Semoga membantu.
sumber
Semua orang menyarankan metode yang kurang optimal
Akan menjadi yang terbaik:
function chars(str) strc = {} for i = 1, #str do table.insert(strc, string.sub(str, i, i)) end return strc end str = "Hello world!" char = chars(str) print("Char 2: "..char[2]) -- prints the char 'e' print("-------------------\n") for i = 1, #str do -- testing printing all the chars if (char[i] == " ") then print("Char "..i..": [[space]]") else print("Char "..i..": "..char[i]) end end
sumber
Iterasi untuk membuat string dan mengembalikan string ini sebagai tabel dengan load () ...
itab=function(char) local result for i=1,#char do if i==1 then result=string.format('%s','{') end result=result..string.format('\'%s\'',char:sub(i,i)) if i~=#char then result=result..string.format('%s',',') end if i==#char then result=result..string.format('%s','}') end end return load('return '..result)() end dump=function(dump) for key,value in pairs(dump) do io.write(string.format("%s=%s=%s\n",key,type(value),value)) end end res=itab('KOYAANISQATSI') dump(res)
Mengeluarkan...
1=string=K 2=string=O 3=string=Y 4=string=A 5=string=A 6=string=N 7=string=I 8=string=S 9=string=Q 10=string=A 11=string=T 12=string=S 13=string=I
sumber