Array

Array #

Array PHP adalah struktur data yang jauh lebih fleksibel dari yang terlihat di permukaan. Di baliknya, semua array PHP adalah ordered map — peta yang mempertahankan urutan insertion, mendukung key integer maupun string dalam satu array yang sama, dan bisa berfungsi sebagai list, dictionary, stack, queue, atau bahkan set sekaligus tergantung cara memakainya. PHP memiliki lebih dari 70 fungsi bawaan khusus untuk array — tapi tidak semua perlu dihapal. Yang penting adalah menguasai pola-pola yang paling sering muncul: transformasi dengan array_map, filter dengan array_filter, agregasi dengan array_reduce, sorting dengan usort, dan pengambilan kolom dengan array_column. Artikel ini membahas semua aspek array PHP secara mendalam beserta pola-pola idiomatik yang membuat kode lebih bersih dari loop eksplisit.

Mendefinisikan Array #

PHP mendukung dua sintaks untuk membuat array: array() yang klasik dan [] yang modern dan ringkas. Gunakan [] untuk semua kode baru.

<?php
// Sintaks modern (PHP 5.4+) — gunakan ini
$kosong      = [];
$terindeks   = [1, 2, 3, 4, 5];
$asosiatif   = ['nama' => 'Budi', 'umur' => 28, 'kota' => 'Jakarta'];
$campuran    = [0 => 'nol', 'satu' => 1, 2 => 'dua']; // valid tapi hindari

// Sintaks lama — masih valid, tapi tidak idiomatik
$terindeksLama = array(1, 2, 3);
$asosiatifLama = array('nama' => 'Budi', 'umur' => 28);

// Array multidimensi
$tabel = [
    ['id' => 1, 'nama' => 'Laptop',  'harga' => 15_000_000, 'stok' => 5],
    ['id' => 2, 'nama' => 'Monitor', 'harga' => 5_000_000,  'stok' => 12],
    ['id' => 3, 'nama' => 'Mouse',   'harga' => 250_000,    'stok' => 0],
    ['id' => 4, 'nama' => 'Keyboard','harga' => 800_000,    'stok' => 8],
];

// Akses elemen
echo $terindeks[0];          // 1
echo $asosiatif['nama'];     // Budi
echo $tabel[1]['nama'];      // Monitor
echo $tabel[0]['harga'];     // 15000000

Array adalah Ordered Map #

PHP array bukan sekadar list — setiap elemen memiliki key yang bisa berupa integer atau string. Memahami ini penting karena unset() tidak mereset indeks:

<?php
$a = ['apel', 'mangga', 'jeruk', 'anggur'];
// Key:    0       1        2        3

unset($a[1]); // hapus 'mangga'
print_r($a);
// Array ( [0] => apel [2] => jeruk [3] => anggur )
// Indeks 1 HILANG — tidak di-reindex otomatis!

// Untuk reindex setelah unset, gunakan array_values()
$a = array_values($a);
print_r($a);
// Array ( [0] => apel [1] => jeruk [2] => anggur )

Menambah, Mengubah, dan Menghapus Elemen #

<?php
$buah = ['apel', 'mangga'];

// Tambah di akhir
$buah[]      = 'jeruk';          // indeks otomatis — sekarang [0,1,2]
$buah[]      = 'anggur';
array_push($buah, 'semangka');   // sama dengan $buah[] = 'semangka'

// Tambah di awal
array_unshift($buah, 'alpukat'); // [alpukat, apel, mangga, jeruk, anggur, semangka]

// Hapus dari akhir — mengembalikan elemen yang dihapus
$terakhir = array_pop($buah);    // 'semangka'

// Hapus dari awal — mengembalikan elemen yang dihapus
$pertama  = array_shift($buah);  // 'alpukat'

// Hapus elemen tertentu
unset($buah[2]);                 // indeks 2 hilang, tidak di-reindex

// Ubah nilai
$buah[0] = 'apel merah';        // override elemen pertama

// Sisipkan di posisi tertentu dengan array_splice()
// array_splice($array, $offset, $panjangDihapus, $sisipan)
array_splice($buah, 1, 0, ['kiwi', 'lemon']); // sisipkan di indeks 1 tanpa hapus

Mengakses Elemen dengan Aman #

<?php
$config = ['host' => 'localhost', 'port' => 3306, 'debug' => false];

// Akses langsung — error jika key tidak ada
echo $config['host'];   // localhost

// Null coalescing — aman untuk key yang mungkin tidak ada
echo $config['user']     ?? 'root';     // 'root' — key tidak ada
echo $config['debug']    ?? true;       // false — key ada, nilainya false
echo $config['timeout']  ?? 30;        // 30 — key tidak ada

// array_key_exists — bedakan antara key tidak ada vs nilai null
$data = ['nama' => null];
var_dump(isset($data['nama']));              // false — null dianggap tidak ada oleh isset
var_dump(array_key_exists('nama', $data));  // true  — key ada meski nilainya null

// Akses nested yang aman
$user = ['profil' => ['kota' => 'Jakarta']];
echo $user['profil']['kota']          ?? 'Tidak diketahui'; // Jakarta
echo $user['profil']['negara']        ?? 'Indonesia';       // Indonesia — key tidak ada
echo $user['alamat']['kota']          ?? 'Tidak diketahui'; // Tidak diketahui

Transformasi Array #

Fungsi transformasi menghasilkan array baru tanpa mengubah array aslinya — ini adalah pola yang lebih bersih dari loop eksplisit dengan append.

array_map — Ubah Setiap Elemen #

<?php
$harga = [10000, 25000, 50000, 100000];

// Tambah PPN 11% ke setiap harga
$hargaPpn = array_map(fn($h) => $h * 1.11, $harga);
// [11100, 27750, 55500, 111000]

// Konversi format
$formatRupiah = array_map(
    fn($h) => 'Rp ' . number_format($h, 0, ',', '.'),
    $harga
);
// ['Rp 10.000', 'Rp 25.000', 'Rp 50.000', 'Rp 100.000']

// array_map dengan beberapa array — diiterasi paralel
$nama  = ['Budi', 'Siti', 'Dani'];
$nilai = [85, 92, 78];

$laporan = array_map(
    fn($n, $v) => ['nama' => $n, 'nilai' => $v, 'lulus' => $v >= 70],
    $nama,
    $nilai
);
// [['nama'=>'Budi','nilai'=>85,'lulus'=>true], ...]

// First-class callable — lebih bersih untuk fungsi yang sudah ada
$kata       = ['  halo  ', ' DUNIA ', ' php  '];
$bersih     = array_map(trim(...), $kata);      // trim setiap elemen
$hurufKecil = array_map(strtolower(...), $bersih); // lowercase

array_filter — Pilih Elemen Berdasarkan Kondisi #

<?php
$produk = [
    ['nama' => 'Laptop',  'harga' => 15_000_000, 'stok' => 5],
    ['nama' => 'Monitor', 'harga' => 5_000_000,  'stok' => 0],
    ['nama' => 'Mouse',   'harga' => 250_000,    'stok' => 20],
    ['nama' => 'Keyboard','harga' => 800_000,    'stok' => 0],
];

// Filter produk yang tersedia (stok > 0)
$tersedia = array_filter($produk, fn($p) => $p['stok'] > 0);
// Laptop dan Mouse

// Filter produk mahal (harga > 1 juta)
$mahal = array_filter($produk, fn($p) => $p['harga'] > 1_000_000);
// Laptop dan Monitor

// Tanpa callback — hapus nilai falsy (false, 0, "", null, [])
$data   = [1, 0, 'halo', '', null, false, 2, [], 3];
$bersih = array_filter($data);
// [0=>1, 2=>'halo', 6=>2, 8=>3] — indeks DIPERTAHANKAN

// Reindex setelah filter jika diperlukan
$bersih = array_values(array_filter($data));
// [0=>1, 1=>'halo', 2=>2, 3=>3]

// ANTI-PATTERN: loop eksplisit untuk filter sederhana
$hasil = [];
foreach ($produk as $p) {
    if ($p['stok'] > 0) {
        $hasil[] = $p;
    }
}

// BENAR: array_filter lebih ekspresif
$hasil = array_values(array_filter($produk, fn($p) => $p['stok'] > 0));

array_reduce — Agregasi ke Satu Nilai #

<?php
$items = [
    ['nama' => 'Laptop',  'harga' => 15_000_000, 'qty' => 1],
    ['nama' => 'Mouse',   'harga' => 250_000,    'qty' => 2],
    ['nama' => 'Monitor', 'harga' => 5_000_000,  'qty' => 1],
];

// Hitung total belanja
$total = array_reduce(
    $items,
    fn($carry, $item) => $carry + ($item['harga'] * $item['qty']),
    0  // nilai awal
);
// 15_000_000 + 500_000 + 5_000_000 = 20_500_000

// Buat lookup table dari array
$lookup = array_reduce(
    $items,
    fn($carry, $item) => array_merge($carry, [$item['nama'] => $item['harga']]),
    []
);
// ['Laptop' => 15000000, 'Mouse' => 250000, 'Monitor' => 5000000]

// Lebih efisien dengan spread
$lookup = array_reduce(
    $items,
    fn($carry, $item) => [...$carry, $item['nama'] => $item['harga']],
    []
);

Pipeline: Gabungkan map + filter + reduce #

<?php
$orders = [
    ['id' => 1, 'total' => 150_000,  'status' => 'selesai', 'diskon' => 0],
    ['id' => 2, 'total' => 800_000,  'status' => 'batal',   'diskon' => 0.1],
    ['id' => 3, 'total' => 2_500_000,'status' => 'selesai', 'diskon' => 0.15],
    ['id' => 4, 'total' => 300_000,  'status' => 'selesai', 'diskon' => 0],
    ['id' => 5, 'total' => 900_000,  'status' => 'proses',  'diskon' => 0.05],
];

// Pipeline: filter selesai → hitung setelah diskon → jumlahkan
$pendapatanBersih = array_reduce(
    array_map(
        fn($o) => $o['total'] * (1 - $o['diskon']),       // step 2: hitung net
        array_filter($orders, fn($o) => $o['status'] === 'selesai') // step 1: filter
    ),
    fn($carry, $net) => $carry + $net,                     // step 3: jumlahkan
    0
);
// (150000 * 1) + (2500000 * 0.85) + (300000 * 1) = 2_675_000

array_column — Ambil Kolom dari Array Multidimensi #

array_column adalah salah satu fungsi array paling berguna yang sering diabaikan:

<?php
$users = [
    ['id' => 1, 'nama' => 'Budi',  'email' => '[email protected]',  'role' => 'admin'],
    ['id' => 2, 'nama' => 'Siti',  'email' => '[email protected]',  'role' => 'editor'],
    ['id' => 3, 'nama' => 'Dani',  'email' => '[email protected]',  'role' => 'viewer'],
    ['id' => 4, 'nama' => 'Rina',  'email' => '[email protected]',  'role' => 'editor'],
];

// Ambil satu kolom sebagai array flat
$semuaNama   = array_column($users, 'nama');
// ['Budi', 'Siti', 'Dani', 'Rina']

$semuaEmail  = array_column($users, 'email');
// ['[email protected]', '[email protected]', ...]

// Ambil kolom dengan key dari kolom lain (buat lookup table)
$emailById   = array_column($users, 'email', 'id');
// [1 => '[email protected]', 2 => '[email protected]', ...]

$userByEmail = array_column($users, null, 'email');
// ['[email protected]' => ['id'=>1,'nama'=>'Budi',...], ...]

// Contoh praktis: cari user by ID dengan O(1)
$userById = array_column($users, null, 'id');
$user     = $userById[2] ?? null; // langsung tanpa loop

// Grouping dengan array_reduce + array_column
$byRole = array_reduce(
    $users,
    function($carry, $user) {
        $carry[$user['role']][] = $user;
        return $carry;
    },
    []
);
// ['admin' => [...], 'editor' => [..., ...], 'viewer' => [...]]

Sorting #

PHP menyediakan banyak fungsi sorting. Memilih yang tepat penting karena hasilnya bisa berbeda secara signifikan.

Sorting Dasar #

<?php
$angka = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3];

// sort() — ascending, RESET key
sort($angka);                  // [1,1,2,3,3,4,5,5,6,9]

// rsort() — descending, RESET key
rsort($angka);                 // [9,6,5,5,4,3,3,2,1,1]

// asort() — ascending, PERTAHANKAN key (untuk asosiatif)
$nilai = ['Budi' => 85, 'Siti' => 92, 'Dani' => 78];
asort($nilai);
// ['Dani' => 78, 'Budi' => 85, 'Siti' => 92]

// arsort() — descending, pertahankan key
arsort($nilai);
// ['Siti' => 92, 'Budi' => 85, 'Dani' => 78]

// ksort() — sort by KEY ascending
ksort($nilai);
// ['Budi' => 85, 'Dani' => 78, 'Siti' => 92]

// krsort() — sort by KEY descending
krsort($nilai);

usort — Sorting dengan Kriteria Kustom #

<?php
$produk = [
    ['nama' => 'Laptop',  'harga' => 15_000_000, 'rating' => 4.5],
    ['nama' => 'Monitor', 'harga' => 5_000_000,  'rating' => 4.2],
    ['nama' => 'Mouse',   'harga' => 250_000,    'rating' => 4.8],
    ['nama' => 'Keyboard','harga' => 800_000,    'rating' => 4.1],
];

// Sort by harga ascending
usort($produk, fn($a, $b) => $a['harga'] <=> $b['harga']);

// Sort by harga descending
usort($produk, fn($a, $b) => $b['harga'] <=> $a['harga']);

// Sort by rating descending, lalu nama ascending jika rating sama
usort($produk, fn($a, $b)
    => [$b['rating'], $a['nama']] <=> [$a['rating'], $b['nama']]
);
// Array comparison element-by-element — teknik sorting tuple yang elegan

// uasort() — seperti usort tapi pertahankan key
$ratings = ['Laptop' => 4.5, 'Monitor' => 4.2, 'Mouse' => 4.8];
uasort($ratings, fn($a, $b) => $b <=> $a); // descending, key dipertahankan

// uksort() — sort by key dengan komparator kustom
uksort($ratings, fn($a, $b) => strlen($a) <=> strlen($b)); // sort by panjang nama

Natural Sort — Sorting String yang Mengandung Angka #

<?php
$file = ['file10.txt', 'file2.txt', 'file1.txt', 'file20.txt'];

sort($file);
// ['file1.txt', 'file10.txt', 'file2.txt', 'file20.txt'] — string sort, 10 < 2 :(

natsort($file);
// ['file1.txt', 'file2.txt', 'file10.txt', 'file20.txt'] — natural, benar!

natcasesort($file); // seperti natsort tapi case-insensitive

Pencarian dan Pemeriksaan #

<?php
$buah = ['apel', 'mangga', 'jeruk', 'anggur', 'mangga'];

// Periksa apakah nilai ada
var_dump(in_array('jeruk', $buah));           // true
var_dump(in_array('semangka', $buah));        // false
var_dump(in_array('0', [false, null, '']));   // true! — gunakan strict mode

// Strict mode — perbandingan ===
var_dump(in_array('0', [false, null, ''], true)); // false — strict

// Cari indeks/key dari nilai
$indeks = array_search('mangga', $buah);  // 1 (pertama yang ditemukan)
var_dump(array_search('semangka', $buah)); // false — tidak ada

// Periksa apakah key ada
var_dump(array_key_exists('nama', ['nama' => null, 'umur' => 28])); // true
var_dump(isset(['nama' => null]['nama']));                            // false!

// Dapatkan semua key atau semua value
$assoc  = ['a' => 1, 'b' => 2, 'c' => 3];
$keys   = array_keys($assoc);    // ['a', 'b', 'c']
$values = array_values($assoc);  // [1, 2, 3]

// array_keys dengan filter nilai — cari semua key dengan nilai tertentu
$duplikat = ['apel', 'mangga', 'jeruk', 'mangga', 'apel'];
$keyMangga = array_keys($duplikat, 'mangga'); // [1, 3]

Penggabungan dan Pemisahan #

<?php
// array_merge — key string dari kanan override kiri
$default = ['timeout' => 30, 'retry' => 3, 'debug' => false];
$custom  = ['timeout' => 10, 'host' => 'api.example.com'];
$config  = array_merge($default, $custom);
// ['timeout'=>10, 'retry'=>3, 'debug'=>false, 'host'=>'api.example.com']

// Spread operator — seperti merge tapi lebih ringkas
$config2 = [...$default, ...$custom];
// Hasil identik dengan array_merge untuk array non-integer key

// PERHATIAN: array_merge vs + (union)
$a = ['x' => 1, 'y' => 2];
$b = ['y' => 9, 'z' => 3];
print_r(array_merge($a, $b)); // y => 9 (kanan menang)
print_r($a + $b);             // y => 1 (kiri menang!)

// array_slice — ambil potongan array
$angka    = [10, 20, 30, 40, 50, 60];
$potongan = array_slice($angka, 1, 3);          // [20, 30, 40]
$akhir    = array_slice($angka, -2);             // [50, 60]
$denganKey= array_slice($angka, 1, 3, true);    // [1=>20, 2=>30, 3=>40]

// array_chunk — bagi array ke beberapa bagian
$data  = range(1, 10);
$batch = array_chunk($data, 3);
// [[1,2,3], [4,5,6], [7,8,9], [10]]

$batchDenganKey = array_chunk($data, 3, true); // pertahankan key

// array_combine — gabungkan dua array jadi key-value
$nama  = ['Budi', 'Siti', 'Dani'];
$skor  = [85, 92, 78];
$hasil = array_combine($nama, $skor);
// ['Budi' => 85, 'Siti' => 92, 'Dani' => 78]

Operasi Set — Unik, Interseksi, Perbedaan #

<?php
$a = [1, 2, 3, 4, 5];
$b = [3, 4, 5, 6, 7];

// Elemen unik dari $a yang tidak ada di $b (difference)
$hanyaDiA = array_diff($a, $b);     // [0=>1, 1=>2]

// Elemen unik dari $b yang tidak ada di $a
$hanyaDiB = array_diff($b, $a);     // [3=>6, 4=>7]

// Elemen yang ada di keduanya (intersection)
$keduanya = array_intersect($a, $b); // [2=>3, 3=>4, 4=>5]

// Hapus duplikat
$duplikat = [1, 2, 2, 3, 3, 3, 4];
$unik     = array_unique($duplikat); // [0=>1, 1=>2, 3=>3, 6=>4]
$unikReindex = array_values(array_unique($duplikat)); // [1,2,3,4]

// Operasi pada array asosiatif
$profil1 = ['nama' => 'Budi', 'kota' => 'Jakarta', 'umur' => 28];
$profil2 = ['nama' => 'Budi', 'kota' => 'Bandung',  'hobi' => 'coding'];

$bedaNilai     = array_diff_assoc($profil1, $profil2); // ['kota'=>'Jakarta']
$bedaKey       = array_diff_key($profil1, $profil2);   // ['umur'=>28]
$samaNilaiKey  = array_intersect_assoc($profil1, $profil2); // ['nama'=>'Budi']

Array sebagai Stack dan Queue #

<?php
// Stack — LIFO (Last In, First Out)
$stack = [];
array_push($stack, 'pertama');  // atau: $stack[] = 'pertama'
array_push($stack, 'kedua');
array_push($stack, 'ketiga');

$top = array_pop($stack);       // 'ketiga' — ambil dari atas
echo array_pop($stack);         // 'kedua'

// Queue — FIFO (First In, First Out)
$queue = [];
array_push($queue, 'antrian1');
array_push($queue, 'antrian2');
array_push($queue, 'antrian3');

$depan = array_shift($queue);   // 'antrian1' — ambil dari depan (FIFO)

// Deque — Double-ended queue
$deque = ['tengah'];
array_unshift($deque, 'depan');   // tambah ke depan
array_push($deque, 'belakang');   // tambah ke belakang
$dari_depan    = array_shift($deque);  // ambil dari depan
$dari_belakang = array_pop($deque);    // ambil dari belakang

Fungsi Matematika pada Array #

<?php
$data = [5, 3, 8, 1, 9, 2, 7, 4, 6];

echo min($data);          // 1
echo max($data);          // 9
echo array_sum($data);    // 45
echo array_product($data); // 362880 (5 × 3 × 8 × 1 × ... × 6)

// Rata-rata
$rata = array_sum($data) / count($data); // 5

// Fungsi matematika lanjutan (butuh array terurut)
sort($data);
$median = $data[intdiv(count($data), 2)]; // elemen tengah

// array_fill dan array_fill_keys
$defaultStok = array_fill(0, 5, 0);   // [0,0,0,0,0] — 5 nol mulai indeks 0
$defaultConfig = array_fill_keys(
    ['debug', 'cache', 'log'],
    false
); // ['debug'=>false, 'cache'=>false, 'log'=>false]

// range() — buat array berurutan
$angka1to10 = range(1, 10);           // [1,2,3,4,5,6,7,8,9,10]
$genap      = range(0, 20, 2);        // [0,2,4,6,8,10,12,14,16,18,20]
$huruf      = range('a', 'f');        // ['a','b','c','d','e','f']

array_walk dan array_map — Kapan Mana #

<?php
$harga = ['laptop' => 15_000_000, 'mouse' => 250_000, 'monitor' => 5_000_000];

// array_map — hasilkan array BARU, tidak ubah asli
$hargaPpn = array_map(fn($h) => $h * 1.11, $harga);
// $harga tidak berubah

// array_walk — modifikasi array IN-PLACE via referensi
// Callback menerima: &$nilai, $key, $data_tambahan (opsional)
array_walk($harga, function(&$nilai, $key) {
    $nilai = $nilai * 1.11;
}); // $harga sekarang berisi harga + PPN

// array_walk_recursive — traversal array multidimensi
$nested = ['a' => [1, 2], 'b' => [3, 4], 'c' => 5];
array_walk_recursive($nested, function(&$nilai) {
    $nilai *= 2;
});
// ['a' => [2, 4], 'b' => [6, 8], 'c' => 10]

Ringkasan #

  • Semua array PHP adalah ordered map — mempertahankan urutan insertion, mendukung key integer dan string. unset() tidak mereset indeks — gunakan array_values() untuk reindex.
  • array_map untuk transformasi (hasilkan array baru), array_filter untuk seleksi (pertahankan sebagian elemen), array_reduce untuk agregasi (jadikan satu nilai) — kombinasi ketiganya membentuk pipeline data yang ekspresif.
  • array_column adalah cara paling ringkas mengekstrak kolom dari array multidimensi, dan dengan argumen ketiga bisa membangun lookup table [key => row] untuk pencarian O(1).
  • usort + spaceship operator <=> adalah cara idiomatik sorting dengan kriteria kustom. Untuk multi-kriteria, bandingkan array secara langsung: [$a['harga'], $a['nama']] <=> [$b['harga'], $b['nama']].
  • in_array dengan strict mode (true sebagai argumen ketiga) mencegah konversi tipe yang tidak diinginkan seperti in_array('0', [false]) yang menghasilkan true tanpa strict.
  • array_merge vs + (union) — perbedaan kritis: array_merge membiarkan key dari kanan menang untuk key string; + mempertahankan key dari kiri. Untuk numeric key, array_merge mereset indeks, + tidak.
  • Spread operator [...$a, ...$b] adalah alternatif modern array_merge yang lebih ringkas dan bisa digunakan langsung dalam ekspresi.
  • array_unique diikuti array_values — untuk mendapatkan array unik dengan indeks yang bersih. array_unique sendiri mempertahankan key asli yang bisa berlubang.

← Sebelumnya: Eksepsi   Berikutnya: Date & Time →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact