Fungsi array mengolah seluruh isi array sekaligus, mulai dari menghitung jumlah elemen, mengurutkan, membalik urutan, hingga menyusunnya menjadi satu string. Topik ini membahas scalar, sort, reverse, dan join, disertai pengenalan grep dan map sebagai penyaring dan pengubah list. Contohnya berupa nilai ujian dan nama peserta, dan setiap skrip dijalankan sehingga keluarannya dapat dibandingkan dengan penjelasannya.
Jumlah elemen dan pengurutan numerik#
Satu array dapat digunakan dalam dua konteks sekaligus, dan perlakuannya berbeda. Pada konteks list, array berperilaku sebagai daftar elemen, sedangkan pada konteks scalar array menghasilkan jumlah elemennya. Fungsi scalar memaksa konteks scalar secara eksplisit, sehingga scalar(@nilai) selalu berupa banyaknya elemen, apa pun posisinya dalam ekspresi.
Fungsi sort mengurutkan elemen dan mengembalikan list baru tanpa mengubah array asalnya. Tanpa blok perbandingan, sort mengurutkan elemen sebagai string menurut urutan karakternya. Untuk angka, urutan string tidak sesuai urutan nilai, sehingga blok perbandingan { $a <=> $b } perlu disertakan. Di dalam blok itu, $a dan $b merupakan sepasang elemen yang sedang dibandingkan, sedangkan operator <=> adalah perbandingan numerik yang mengembalikan nilai negatif, nol, atau positif. Dengan blok tersebut, sort menghasilkan urutan dari kecil ke besar, dan elemen pertamanya langsung menjadi nilai terkecil.
Konteks scalar juga terbentuk tanpa fungsi scalar, yaitu ketika array ditugaskan ke satu variabel skalar. Penulisan my $banyak = @nilai; menghasilkan jumlah elemen, karena penerima yang berupa satu skalar menentukan konteks ekspresi di sebelah kanannya. Fungsi scalar tetap berguna pada posisi yang ambigu, misalnya di dalam daftar argumen print. Mengenai pengurutan, sort pada Perl 5.40 bersifat stabil, sehingga dua elemen yang nilainya sama mempertahankan urutan relatif asalnya. Sifat ini berguna pada pengurutan bertahap, misalnya daftar yang sudah terurut menurut nama diurutkan kembali menurut nilai, karena peserta dengan nilai yang sama tetap mempertahankan urutan namanya.
use strict;
use warnings;
# nilai ujian lima peserta dalam array
my @nilai = (78, 92, 65, 88, 71);
# scalar memberi tahu jumlah elemen ketika array dipakai di konteks scalar
print "Jumlah peserta: ", scalar(@nilai), "\n";
# sort dengan blok perbandingan numerik mengurutkan dari kecil ke besar
my @naik = sort { $a <=> $b } @nilai;
print "Urut naik : @naik\n";
# elemen pertama hasil pengurutan naik adalah nilai terkecil
print "Nilai terkecil: $naik[0]\n";Jumlah peserta: 5
Urut naik : 65 71 78 88 92
Nilai terkecil: 65Membalik urutan dengan reverse#
Fungsi reverse membalik urutan elemen list apa adanya, tanpa memeriksa besar kecilnya nilai. Hasilnya adalah list baru, sehingga array yang menjadi masukan tetap utuh. Untuk mendapatkan urutan menurun, reverse dirangkai dengan sort numerik, sebagaimana reverse sort { $a <=> $b } @nilai pada skrip berikut. Urutan menurun juga dapat dibentuk dengan menukar posisi $a dan $b menjadi { $b <=> $a }, sehingga tersedia dua cara yang setara dan pilihannya biasanya soal keterbacaan.
Pada konteks scalar, reverse berperilaku berbeda, yaitu menyambung seluruh elemen masukannya lalu membalik susunan karakternya. Pemanggilan reverse "kata" dalam penugasan ke variabel skalar menghasilkan string "atak". Dua perilaku ini berasal dari fungsi yang sama, dan pemisahnya adalah konteks pemanggilannya. Elemen pertama hasil urutan menurun langsung menjadi nilai tertinggi, sebuah pola yang sering digunakan untuk peringkat.
Urutan perangkaiannya menentukan hasil. Rangkaian sort kemudian reverse menghasilkan urutan menurun, sedangkan rangkaian terbaliknya tidak, karena sort mengatur ulang seluruh elemen dan dengan demikian menghapus jejak pembalikan sebelumnya. Oleh karena itu, ekspresi sort reverse 1 .. 5 setara dengan sort 1 .. 5. Selain itu, reverse menerima list apa pun sebagai masukannya, termasuk hasil operator rentang, sehingga pembalikan tidak harus melewati array perantara.
use strict;
use warnings;
# reverse membalik urutan list tanpa memandang isinya
my @angka = (1 .. 5);
print "Dibalik : ", join(" ", reverse @angka), "\n";
# urutan menurun dibentuk dengan merangkai sort dan reverse
my @nilai = (78, 92, 65);
my @turun = reverse sort { $a <=> $b } @nilai;
print "Menurun : @turun\n";
# dalam konteks scalar, reverse membalik susunan karakter sebuah string
my $terbalik = reverse "kata";
print "Teks terbalik: $terbalik\n";Dibalik : 5 4 3 2 1
Menurun : 92 78 65
Teks terbalik: atakMenyusun list menjadi satu string#
Fungsi join menyambung seluruh elemen list menjadi satu string dengan pemisah yang ditentukan pada argumen pertamanya. Pemisahnya boleh berupa string apa pun, misalnya koma diikuti spasi atau tanda hubung. Fungsi ini sering digunakan untuk menyiapkan keluaran yang rapi, seperti daftar nama yang dipisah koma, karena pencetakan array langsung hanya memisahkan elemen dengan spasi. Nilai baliknya selalu berupa satu string, sehingga hasilnya dapat disimpan ke variabel tunggal seperti $daftar pada skrip berikut. Apabila list-nya kosong, join mengembalikan string kosong tanpa peringatan.
Sebelum disambung, elemennya dapat diurutkan lebih dahulu dengan sort tanpa blok. Pengurutan string cocok untuk nama karena urutan abjadnya mengikuti urutan karakternya. Rangkaian sort kemudian join menjadi pola yang lazim untuk menampilkan daftar yang terurut dan tetap mudah dibaca.
Saat disambung, setiap elemen dikonversi menjadi teks, sehingga angka 24 tampil sebagai teks 24 pada hasil akhirnya. Elemen yang bernilai undef menjadi string kosong, tetapi dengan use warnings aktif, Perl menampilkan pesan Use of uninitialized value in join or string sebagaimana perilaku pencetakan nilai yang belum terisi. Pemisah berupa string kosong menjadikan join penyambung murni, sehingga join("", @kata) menghasilkan satu rangkaian tanpa pemisah apa pun. Masukannya tidak harus array, karena hasil grep, map, atau operator rentang dapat langsung disambung pada panggilan yang sama.
use strict;
use warnings;
# daftar nama peserta pelatihan
my @nama = ("Dewi", "Ali", "Citra", "Budi");
# sort tanpa blok mengurutkan elemen sebagai string
my @urut = sort @nama;
print "Urut abjad: @urut\n";
# join menyusun seluruh elemen menjadi satu string dengan pemisah
my $daftar = join(", ", @urut);
print "Daftar : $daftar\n";
# pemisah boleh berupa string apa pun, termasuk tanda hubung
my @angka = (1 .. 5);
print "Kode : ", join("-", @angka), "\n";Urut abjad: Ali Budi Citra Dewi
Daftar : Ali, Budi, Citra, Dewi
Kode : 1-2-3-4-5Mengenali grep dan map#
Dua fungsi berikut bekerja pada seluruh list sekaligus dan menjadi fondasi pengolahan data yang ringkas. Fungsi grep menyalin elemen yang lolos uji pada bloknya, sedangkan elemen yang gagal dibuang. Di dalam blok, variabel $_ berisi elemen yang sedang diperiksa, sehingga uji $_ >= 75 berarti hanya nilai minimal 75 yang masuk hasil. Fungsi map mengubah setiap elemen menjadi nilai baru menurut ekspresi pada bloknya, sehingga map { $_ + 5 } menambah lima pada setiap angka.
Keduanya tidak mengubah array asal, melainkan mengembalikan list baru, dan keduanya dapat dirangkai. Pada skrip berikut, hasil grep menjadi masukan map, sehingga penyaringan dan pengubahan terjadi dalam satu baris. Blok pada grep dan map dievaluasi dalam konteks list, sehingga map bahkan boleh menghasilkan lebih dari satu nilai untuk satu masukan.
Pada konteks scalar, grep mengembalikan banyaknya elemen yang lolos uji, sehingga scalar(grep { $_ >= 75 } @nilai) menghitung jumlah peserta yang lulus tanpa menampung hasilnya ke array. Fungsi map pada konteks yang sama mengembalikan banyaknya nilai yang akan dihasilkannya. Panjang keluaran map boleh berbeda dari panjang masukannya, karena bloknya boleh menghasilkan list kosong untuk elemen tertentu. Kedua fungsi menerima list apa pun dan tidak terbatas pada array, sehingga keduanya dapat diterapkan langsung pada hasil operator rentang.
use strict;
use warnings;
# nilai ujian yang akan diolah
my @nilai = (78, 92, 65, 88, 71);
# grep menyaring elemen yang lolos uji dan membuang sisanya
my @lulus = grep { $_ >= 75 } @nilai;
print "Lolos 75 : @lulus\n";
print "Jumlahnya : ", scalar(@lulus), "\n";
# map mengubah setiap elemen menjadi nilai baru dengan ekspresi yang diberikan
my @bertambah = map { $_ + 5 } @nilai;
print "Tambah lima : @bertambah\n";
# keduanya dapat dirangkai, hasil grep menjadi masukan map
my @poin = map { $_ * 10 } grep { $_ >= 80 } @nilai;
print "Poin : @poin\n";Lolos 75 : 78 92 88
Jumlahnya : 3
Tambah lima : 83 97 70 93 76
Poin : 920 880Kesalahan umum#
Kesalahan yang paling umum adalah mengurutkan angka tanpa blok perbandingan. sort tanpa blok membandingkan elemen sebagai string, sehingga urutannya mengikuti karakter pertama dan bukan nilai angkanya. Contoh berikut memperlihatkan urutan yang dihasilkan sort tanpa blok pada tiga angka.
use strict;
use warnings;
# sort tanpa blok membandingkan angka sebagai string
my @campur = (8, 71, 100);
print join(" ", sort @campur), "\n";100 71 8Urutan 100 71 8 benar menurut string, tetapi keliru menurut nilai. Perbaikannya sama seperti pada bagian sebelumnya, yaitu menambahkan blok { $a <=> $b } agar perbandingannya numerik. Tidak ada pesan peringatan untuk kasus ini, sehingga urutan yang keliru hanya terlihat dari keluarannya. Kesalahan kedua adalah mengira sort mengubah array asalnya, padahal fungsi ini mengembalikan list baru, sehingga hasilnya harus ditugaskan ke variabel atau langsung digunakan. Apabila hasil pengurutan tidak pernah disimpan, pengurutan itu hilang bersama ekspresinya.
Ringkasan#
scalar(@array)memberikan jumlah elemen, sedangkansorttanpa blok mengurutkan sebagai string dansort { $a <=> $b }mengurutkan secara numerik.reversemembalik urutan list, dan dirangkai dengansortuntuk membentuk urutan menurun, sedangkan pada konteks scalarreversemembalik karakter sebuah string.joinmenyambung list menjadi satu string dengan pemisah tertentu, dan nilai baliknya selalu berupa skalar.grepmenyaring elemen yang lolos uji,mapmengubah setiap elemen, dan keduanya mengembalikan list baru tanpa menyentuh array asalnya.
Referensi#
- perlfunc — Perl documentation
— Daftar fungsi bawaan Perl, termasuk
scalar,sort,reverse,join,grep, danmap. - perlvar — Perl documentation
— Uraian variabel
$a,$b, dan$_yang digunakan di dalam blok perbandingan dan penyaringan.