Operasi Set dan Stack

in_array, array_unique, push/pop, dan array_merge.

Daftar isi

Array dapat diperlakukan sebagai set, yaitu kumpulan yang diuji keanggotaannya dan dibersihkan dari duplikat, maupun sebagai stack dan antrean yang diolah dari ujung array. Topik ini membahas in_array() dan array_search() untuk keanggotaan, array_unique(), array_diff(), dan array_intersect() untuk keunikan serta selisih, operasi push, pop, shift, dan unshift untuk ujung array, lalu array_merge() untuk penggabungan. Setelah membacanya, operasi-operasi tersebut dapat dipilih sesuai bentuk data yang diolah.

Fungsi in_array() memeriksa apakah sebuah nilai terdapat pada array dan mengembalikan true atau false. Fungsi array_search() melakukan pemeriksaan yang sama dan mengembalikan kunci elemen pertama yang cocok, atau false apabila tidak ada. Hasil array_search() perlu dibandingkan dengan !== false karena kunci 0 bernilai sama dengan false pada pembanding longgar, sedangkan pembanding ketat membedakan keduanya.

Secara bawaan keduanya membandingkan nilai secara longgar, sehingga string '7' dianggap sama dengan bilangan 7. Argumen ketiga bernilai true mengubah perbandingannya menjadi ketat sehingga tipe nilai ikut diuji.

Contoh berikut menguji keanggotaan nama pada daftar hadir, lalu memperlihatkan perbedaan pembanding longgar dan ketat.

php uji-anggota.php
<?php

$hadir = ['Ali', 'Budi', 'Citra'];

var_dump(in_array('Budi', $hadir));
var_dump(in_array('7', [7]));
var_dump(in_array('7', [7], true));

$kunci = array_search('Citra', $hadir);

var_dump($kunci);
var_dump(array_search('Dewi', $hadir));
text Keluaran
bool(true)
bool(true)
bool(false)
int(2)
bool(false)

Pembanding longgar menyetarakan '7' dengan 7, dan pembanding ketat menolaknya karena tipenya berbeda. array_search() mengembalikan kunci 2 untuk 'Citra' dan false untuk 'Dewi' yang tidak terdaftar.

Keunikan, irisan, dan selisih#

Fungsi array_unique() membuang nilai yang berulang dan menyisakan kemunculan pertamanya, dengan kunci elemen yang tersisa dipertahankan. Fungsi array_intersect() mengembalikan nilai yang terdapat pada seluruh array yang dibandingkan, sedangkan array_diff() mengembalikan nilai yang hanya terdapat pada array pertama. Ketiganya membandingkan nilai sebagai string secara bawaan, sehingga 1 dan '1' dianggap nilai yang sama oleh array_unique().

Kunci pada hasil array_intersect() dan array_diff() diambil dari array pertama, sehingga hasilnya juga dapat berlubang dan array_values() menyusunnya kembali apabila diperlukan.

Contoh berikut menggabungkan dua daftar belanja, membersihkan duplikatnya, lalu mencari barang yang sama dan barang yang hanya ada pada daftar pertama.

php unik-dan-selisih.php
<?php

$belanjaAli = ['beras', 'telur', 'gula'];
$belanjaDewi = ['gula', 'minyak', 'beras'];

$gabungan = array_merge($belanjaAli, $belanjaDewi);

print_r($gabungan);
print_r(array_values(array_unique($gabungan)));
print_r(array_intersect($belanjaAli, $belanjaDewi));
print_r(array_diff($belanjaAli, $belanjaDewi));
text Keluaran
Array
(
    [0] => beras
    [1] => telur
    [2] => gula
    [3] => gula
    [4] => minyak
    [5] => beras
)
Array
(
    [0] => beras
    [1] => telur
    [2] => gula
    [3] => minyak
)
Array
(
    [0] => beras
    [2] => gula
)
Array
(
    [1] => telur
)

Penggabungan menyalin seluruh isi termasuk duplikatnya, dan array_unique() menyisakan kemunculan pertama setiap barang. Irisan menampilkan beras dan gula yang ada pada kedua daftar, sedangkan selisih menampilkan telur yang hanya terdapat pada daftar pertama.

Stack dan antrean di ujung array#

Operasi ujung array membentuk stack, yaitu struktur terakhir masuk pertama keluar (LIFO, last in, first out). Penambahan dilakukan dengan array_push() atau kurung siku kosong, dan pengambilan dilakukan dengan array_pop(), keduanya pada ujung belakang array. Untuk satu elemen, kurung siku kosong dipilih karena tidak memanggil fungsi.

Bentuk antrean memakai ujung yang berlawanan. Fungsi array_shift() mengambil elemen terdepan dan menyusun ulang seluruh kunci bilangan, sedangkan array_unshift() menyisipkan elemen di depan. Penyusunan ulang inilah yang membuat array_shift() lebih berat daripada array_pop() pada array yang sangat panjang, karena seluruh kuncinya harus digeser.

Contoh berikut mengoperasikan tumpukan tiket loket sebagai stack, lalu mengoperasikan antrean tiket sebagai antrean sungguhan.

php tumpukan-antrean.php
<?php

$tumpukan = [];

array_push($tumpukan, 'T-01');
array_push($tumpukan, 'T-02');
$tumpukan[] = 'T-03';

echo array_pop($tumpukan), "\n";
echo array_pop($tumpukan), "\n";
print_r($tumpukan);

$antrean = ['T-04', 'T-05', 'T-06'];

echo array_shift($antrean), "\n";
array_unshift($antrean, 'T-00');
print_r($antrean);
text Keluaran
T-03
T-02
Array
(
    [0] => T-01
)
T-04
Array
(
    [0] => T-00
    [1] => T-05
    [2] => T-06
)

Tumpukan mengeluarkan T-03 lebih dahulu karena tiket tersebut masuk paling akhir, sedangkan antrean mengeluarkan T-04 yang berdiri paling depan. Penyisipan T-00 di depan antrean menggeser kunci elemen lain tanpa mengubah urutan antreannya.

Menggabungkan array dengan array_merge#

Fungsi array_merge() menggabungkan beberapa array menjadi satu dengan aturan yang bergantung pada jenis kuncinya. Kunci string pada array berikutnya menimpa kunci yang sama pada array sebelumnya, sedangkan kunci bilangan selalu ditambahkan ke belakang dengan kunci baru yang berurutan tanpa memandang nilainya. Operator sebar [...$a, ...$b] memberikan hasil yang sama untuk array terindeks, dan sejak PHP 8.1 juga mendukung kunci string dengan aturan penimpaan yang serupa.

Contoh berikut menggabungkan nilai ujian per mata pelajaran yang kuncinya string, lalu menggabungkan dua array terindeks yang kunci numeriknya sengaja bertabrakan.

php gabung-array.php
<?php

$nilaiPerUjian = ['matematika' => 85];
$nilaiTambah = ['matematika' => 90, 'fisika' => 78];

print_r(array_merge($nilaiPerUjian, $nilaiTambah));

$angka1 = [10, 20];
$angka2 = [0 => 30, 40];

print_r(array_merge($angka1, $angka2));
print_r([...$angka1, ...$angka2]);
text Keluaran
Array
(
    [matematika] => 90
    [fisika] => 78
)
Array
(
    [0] => 10
    [1] => 20
    [2] => 30
    [3] => 40
)
Array
(
    [0] => 10
    [1] => 20
    [2] => 30
    [3] => 40
)

Kunci 'matematika' bernilai 90 karena array kedua menimpanya, sedangkan nilai 30 yang membawa kunci 0 tetap ditambahkan di belakang dengan kunci baru 2. Bentuk operator sebar menghasilkan array yang sama dengan array_merge() untuk kedua kasus tersebut.

Kesalahan umum#

  • Memanggil array_search() tanpa pembanding ketat pada hasilnya. Kunci 0 bernilai sama dengan false pada pembanding longgar, sehingga elemen pertama yang ditemukan dianggap tidak ada. Bandingkan hasilnya dengan !== false.
  • Mengira array_unique() membandingkan nilai tanpa konversi. Perbandingan bawaannya memperlakukan nilai sebagai string, sehingga 1 dan '1' dianggap duplikat. Perilaku ini perlu diwaspadai pada data campuran tipe.
  • Menggunakan array_shift() dalam perulangan panjang pada array besar. Setiap pemanggilan menggeser seluruh kunci, sehingga biayanya bertambah seiring panjang array. Keluarkan elemen dari ujung belakang dengan array_pop() setelah membalik array, atau gunakan struktur antrean yang dirancang untuk itu.
  • Mengira array_merge() menimpa kunci numerik. Kunci bilangan selalu ditambahkan dengan kunci baru yang berurutan, sehingga penggabungan array terindeks tidak menduplikasi kunci, tetapi juga tidak menimpa nilai lama.

Ringkasan#

  • in_array() menguji keanggotaan nilai, array_search() mengembalikan kuncinya, dan argumen ketiga true menegaskan perbandingan ketat.
  • array_unique() menyisakan kemunculan pertama, array_intersect() mengambil irisannya, dan array_diff() mengambil selisihnya dengan kunci dari array pertama.
  • Pasangan array_push() dan array_pop() membentuk stack di ujung belakang, sedangkan array_shift() dan array_unshift() mengolah ujung depan dengan biaya penggeseran kunci.
  • array_merge() menimpa kunci string dan menambahkan kunci bilangan ke belakang, dan operator sebar memberikan perilaku yang sama.

Referensi#