Panduan Pasukan Lucee MY

Fungsi array CFML: himpunan lengkap dengan contoh

Rujukan lengkap fungsi array CFML di Lucee: cipta, tambah, cari, ubah dan proses array dengan arrayMap, arrayFilter, arrayFind dan rakan-rakannya.

Fungsi array CFML: himpunan lengkap dengan contoh
0
Kandungan

Fungsi array CFML: himpunan lengkap dengan contoh

Array ialah struktur data paling kerap anda guna selepas struct. Artikel ini menghimpunkan fungsi array penting mengikut kategori dengan contoh yang diuji dalam Lucee 7.1. Dua perkara perlu difahami dahulu: indeks bermula dari 1, dan array diserahkan secara rujukan.

Bagaimana array berkelakuan dalam CFML

Tiga sifat menentukan cara anda menulis kod array yang betul.

Pertama, indeks bermula dari 1. Elemen pertama ialah senarai[1], bukan senarai[0]. Pembangun dari JavaScript, PHP atau Python paling kerap tersilap di sini.

Kedua, array boleh menyimpan jenis bercampur. Anda boleh letak rentetan, nombor, struct dan array lain dalam satu array yang sama tanpa pengisytiharan jenis.

Ketiga, array diserahkan secara rujukan. Apabila anda menulis b = a, kedua-dua nama menunjuk ke array yang sama. Untuk salinan bebas, guna duplicate():

<cfscript>
    asal = ["Kopi", "Teh"];
    rujukan = asal;
    rujukan[1] = "Koko";
    writeOutput("asal selepas rujukan diubah: " & serializeJSON(asal));

    salinan = duplicate(asal);
    salinan[1] = "Susu";
    writeOutput(" | asal selepas salinan diubah: " & serializeJSON(asal) & " salinan: " & serializeJSON(salinan));
</cfscript>

rujukan[1] menukar asal kerana kedua-duanya satu array. Selepas duplicate(), salinan bebas daripada asal. Peraturan ini terpakai juga apabila anda menghantar array ke fungsi.

Fungsi mencipta dan menambah

Untuk mencipta array kosong, guna arrayNew(1) atau literal []. Tambah elemen dengan arrayAppend di hujung, arrayPrepend di hadapan, dan arrayInsertAt pada posisi tertentu. arrayResize mengubah saiz array dan mengisi kedudukan baharu dengan null.

<cfscript>
    keranjang = arrayNew(1);
    arrayAppend(keranjang, "Kopi");
    arrayAppend(keranjang, "Teh");
    arrayPrepend(keranjang, "Roti");
    arrayInsertAt(keranjang, 2, "Kek");
    arrayResize(keranjang, 6);
    writeOutput(serializeJSON(keranjang));
</cfscript>

Ini mencetak ["Roti","Kek","Kopi","Teh",null,null]. Roti masuk ke hadapan, Kek menolak Kopi dan Teh ke kanan, kemudian arrayResize menambah dua kedudukan kosong.

Fungsi membaca dan mencari

Untuk membaca saiz dan keadaan array, guna arrayLen untuk bilangan elemen dan arrayIsEmpty untuk menyemak kekosongan. Untuk mencari nilai, guna arrayFind atau arrayContains, masing-masing dengan varian NoCase untuk carian tanpa sensitif huruf besar kecil.

<cfscript>
    nama = ["Ali", "Siti", "Raju", "siti"];
    writeOutput("Panjang: " & arrayLen(nama));
    writeOutput(" | Kosong? " & arrayIsEmpty(nama));
    writeOutput(" | Siti di indeks: " & arrayFind(nama, "Siti"));
    writeOutput(" | siti tanpa kes: " & arrayFindNoCase(nama, "siti"));
    writeOutput(" | Raju di indeks: " & arrayContains(nama, "Raju"));
</cfscript>

Satu perkara penting: dalam Lucee, arrayContains TIDAK memulangkan boolean. Ia memulangkan kedudukan elemen pertama yang sepadan, atau 0 apabila tiada, sama seperti arrayFind. Semak hasilnya terhadap 0, bukan true.

arrayFind dan arrayContains sensitif huruf besar kecil, jadi kedua-duanya hanya menemui Siti pada indeks 2. Varian NoCase turut menemui siti. Gunakan versi NoCase untuk input manusia.

Apabila nilai muncul lebih daripada sekali, arrayFindAll memulangkan semua indeks sebagai array:

<cfscript>
    markah = [80, 55, 90, 55, 70];
    lokasi = arrayFindAll(markah, 55);
    writeOutput(serializeJSON(lokasi));
</cfscript>

Ini mencetak [2,4], iaitu dua kedudukan nilai 55. Fungsi ini berguna untuk mencari semua padanan sebelum bertindak, contohnya menandai semua rekod yang gagal.

Fungsi mengubah

Fungsi mengubah terbahagi dua: yang mengubah array di tempatnya, dan yang memulangkan array baharu. arraySort, arrayDelete, arrayDeleteAt dan arrayClear mengubah array asal. arrayReverse dan arraySlice memulangkan array baharu.

<cfscript>
    nombor = [3, 1, 2];
    arraySort(nombor, "numeric", "asc");
    terbalik = arrayReverse(nombor);
    hirisan = arraySlice(nombor, 1, 2);
    writeOutput(serializeJSON({ asal: nombor, terbalik: terbalik, hirisan: hirisan }));
</cfscript>

arraySort menerima array, jenis susunan (numeric, text, textnocase) dan tertib (asc atau desc). Tanpa jenis, ia menyusun sebagai teks, jadi 10 duduk sebelum 2. Sentiasa nyatakan numeric untuk nombor.

Selepas arraySort, nombor menjadi [1,2,3]. arrayReverse(nombor) memulangkan [3,2,1] tanpa mengubah nombor, jadi tetapkan semula untuk membalikkan array asal. arraySlice juga memulangkan salinan; argumennya ialah array, indeks mula, dan bilangan elemen.

<cfscript>
    senarai = ["a", "b", "c", "d"];
    arrayDeleteAt(senarai, 2);
    arrayDelete(senarai, "d");
    writeOutput(arrayToList(senarai, ","));
    arrayClear(senarai);
    writeOutput(" | kosong selepas clear? " & arrayIsEmpty(senarai));
</cfscript>

arrayDeleteAt membuang mengikut indeks, manakala arrayDelete membuang mengikut nilai. Selepas arrayDeleteAt(senarai, 2), senarai menjadi a,c,d, kemudian arrayDelete(senarai, "d") meninggalkan a,c. arrayClear mengosongkan array di tempatnya.

Fungsi lanjutan

Keluarga fungsi penutup membolehkan anda memproses array secara deklaratif tanpa gelung for panjang, sama seperti map, filter dan reduce dalam JavaScript.

<cfscript>
    harga = [10, 20, 30];
    diskaun = arrayMap(harga, function(n) { return n * 0.9; });
    mahal = arrayFilter(harga, function(n) { return n > 15; });
    jumlah = arrayReduce(harga, function(acc, n) { return acc + n; }, 0);
    writeOutput(serializeJSON({ diskaun: diskaun, mahal: mahal, jumlah: jumlah }));
</cfscript>

arrayMap memulangkan array baharu dengan setiap elemen ditukar oleh penutup. arrayFilter mengekalkan elemen yang penutupnya memulangkan true. arrayReduce melipat array menjadi satu nilai bermula daripada nilai awal anda.

arrayEach melintasi array untuk kesan sampingan, bukan untuk membina nilai baharu. Penutupnya boleh menulis ke pemboleh ubah di luar skopnya:

<cfscript>
    nama = ["Ali", "Siti"];
    jumlahHuruf = 0;
    arrayEach(nama, function(n) { jumlahHuruf += len(n); });
    writeOutput(jumlahHuruf);
</cfscript>

arraySome memulangkan true jika ada satu elemen memenuhi syarat, arrayEvery memerlukan semua elemen memenuhinya:

<cfscript>
    umur = [18, 21, 16, 25];
    adaDewasa = arraySome(umur, function(n) { return n >= 21; });
    semuaDewasa = arrayEvery(umur, function(n) { return n >= 18; });
    writeOutput("Ada 21 ke atas: " & adaDewasa & " | Semua 18 ke atas: " & semuaDewasa);
</cfscript>

Untuk nombor, arraySum menjumlahkan, arrayAvg mengira purata, arrayMin dan arrayMax mengambil nilai terendah dan tertinggi. Tiada sum() generik dalam Lucee, anda mesti guna arraySum().

<cfscript>
    markah = [70, 80, 90];
    writeOutput(serializeJSON({
        jumlah: arraySum(markah),
        purata: arrayAvg(markah),
        terendah: arrayMin(markah),
        tertinggi: arrayMax(markah)
    }));
</cfscript>

Kesilapan biasa dan cara betul

Dua kesilapan berulang dalam kod CFML sebenar, kedua-duanya berpunca daripada andaian indeks berasaskan sifar.

Kesilapan pertama ialah off-by-one. Gelung for (i = 0; i < arrayLen(senarai); i++) melintasi dari 0, jadi ia menyentuh indeks 0 yang tidak wujud dan terlepas elemen terakhir.

<cfscript>
    senarai = ["a", "b", "c", "d"];
    for (i = 0; i < arrayLen(senarai); i++) {
        try {
            writeOutput(senarai[i]);
        } catch (any e) {
            writeOutput("[Ralat: " & e.message & "]");
        }
    }
</cfscript>

Outputnya ialah ralat Array index [0] out of range diikuti abc, dan huruf d hilang. Cara betul: mula dari 1 dan guna <=, atau terus guna arrayEach.

Kesilapan kedua ialah menyunting array semasa melintasinya ke hadapan. Apabila anda memadam elemen, indeks beralih ke kiri dan elemen seterusnya dilangkau. Di sini kita mahu membuang semua nilai di bawah 3, tetapi 2 terselamat:

<cfscript>
    senarai = [1, 2, 3, 4];
    for (i = 1; i <= arrayLen(senarai); i++) {
        if (senarai[i] < 3) { arrayDeleteAt(senarai, i); }
    }
    writeOutput(serializeJSON(senarai));
</cfscript>

Outputnya [2,3,4], bukan [3,4]. Selepas indeks 1 dipadam, nilai 2 meluncur ke indeks 1, tetapi gelung sudah bergerak ke indeks 2. Lintas dari belakang:

<cfscript>
    senarai = [1, 2, 3, 4];
    for (i = arrayLen(senarai); i >= 1; i--) {
        if (senarai[i] < 3) { arrayDeleteAt(senarai, i); }
    }
    writeOutput(serializeJSON(senarai));
</cfscript>

Pendekatan arrayFilter lebih ringkas dan mengelakkan masalah indeks sepenuhnya:

<cfscript>
    senarai = [1, 2, 3, 4];
    senarai = arrayFilter(senarai, function(n) { return n >= 3; });
    writeOutput(serializeJSON(senarai));
</cfscript>

Jadual rujukan pantas

KategoriFungsiTujuan
CiptaarrayNew, []Cipta array kosong
TambaharrayAppend, arrayPrepend, arrayInsertAt, arrayResizeTambah elemen atau ubah saiz
BacaarrayLen, arrayIsEmptySaiz dan keadaan
CariarrayFind, arrayFindNoCase, arrayContains, arrayContainsNoCase, arrayFindAllCari nilai dan kedudukan
UbaharraySort, arrayReverse, arraySlice, arrayDelete, arrayDeleteAt, arrayClearSusun, terbalik, hirisan, buang
ProsesarrayMap, arrayFilter, arrayReduce, arrayEach, arraySome, arrayEveryPenutup deklaratif
StatistikarrayAvg, arraySum, arrayMin, arrayMaxAgregat nombor

Untuk koleksi pasangan nama dan nilai, lihat fungsi struct CFML, kerana struct melengkapi array. Jika anda masih menulis array dalam bentuk tag, bandingkan dengan tag lawan script syntax. Gelung for dan each yang digabungkan dengan array dibincang lebih dalam dalam gelung dan kondisional. Ingat juga bahawa pemboleh ubah array hidup dalam skop tertentu, jadi baca memahami scope CFML sebelum menghantar array merentasi fungsi.

Soalan Lazim (FAQ)

Adakah indeks array CFML bermula dari 0 atau 1?

Ia bermula dari 1. Elemen pertama ialah senarai[1], dan membaca senarai[0] melemparkan ralat Array index [0] out of range. Ini beza utama berbanding JavaScript, PHP dan Python yang bermula dari 0.

Bagaimana cara menyalin array tanpa berkongsi rujukan?

Guna duplicate(asal). Tugasan biasa b = a hanya mencipta nama kedua untuk array yang sama. duplicate() menghasilkan salinan bebas.

Apakah beza antara arrayFind dan arrayContains?

Dalam Lucee, hampir tiada beza: kedua-duanya memulangkan kedudukan elemen pertama yang sepadan, atau 0 jika tiada, dan kedua-duanya sensitif huruf besar kecil. Beza utama ialah arrayContains memulangkan boolean dalam Adobe ColdFusion, jadi kod ColdFusion mungkin pecah di Lucee. Semak hasilnya terhadap 0.

Bolehkah array CFML menyimpan jenis data bercampur?

Boleh. Satu array boleh mengandungi rentetan, nombor, struct dan array lain tanpa pengisytiharan jenis. Dalam kod pengeluaran lebih selamat untuk mengekalkan satu jenis setiap array.

Bagaimana cara membuang semua elemen yang memenuhi syarat?

Guna arrayFilter untuk membina array baharu yang hanya mengandungi elemen yang lulus syarat, atau lintas array dari belakang dengan arrayDeleteAt. Jangan lintas ke hadapan sambil memadam, kerana indeks beralih dan elemen dilangkau.

Sumber

Senarai semak

  1. Semua gelung for ke atas array bermula dari indeks 1 dan berakhir dengan <= arrayLen().
  2. Salinan bebas dibuat dengan duplicate(), bukan tugasan terus.
  3. arraySort diberi jenis numeric untuk nombor, bukan teks.
  4. Elemen tidak dipadam semasa melintasi array ke hadapan; guna lintasan songsang atau arrayFilter.
  5. Hasil arrayFind dan arrayContains disemak terhadap 0, bukan true atau false, kerana kedua-duanya memulangkan kedudukan dalam Lucee.
  6. Hasil arrayReverse dan arraySlice ditetapkan kepada pemboleh ubah, kerana kedua-duanya memulangkan array baharu.
Bab 6 daripada 10

Asas CFML untuk Pemula

Log masuk untuk menyimpan kemajuan bacaan anda.

0 komen

0 komen

Log masuk untuk menjawab atau memberi komen.

Log masuk