arrayfungsiagregasiMenengah3 mnt baca

Melebur Array dengan array_reduce

Lebur seluruh isi array menjadi satu nilai: total, kalimat, atau struktur baru.

Kenapa array_reduce Ada?

array_map mengubah N item menjadi N item, array_filter menyisakan sebagian. Tapi bagaimana "N item menjadi satu nilai"? Total harga keranjang, kalimat dari daftar kata, HTML tabel dari array produk. Itulah array_reduce: ia melipat array item demi item ke dalam satu akumulator yang dibawa antar putaran.

php
<?php
// Contoh 1: total keranjang (lebih fleksibel dari array_sum)
$keranjang = [
    ["nama" => "Kopi", "harga" => 15000, "qty" => 2],
    ["nama" => "Roti", "harga" => 12000, "qty" => 1],
];

$total = array_reduce($keranjang, function ($bawa, $item) {
    return $bawa + ($item["harga"] * $item["qty"]);
}, 0);   // 0 = nilai awal akumulator

echo $total;   // 42000

Cara membacanya: $bawa mulai dari 0. Putaran 1: 0 + 30000 = 30000. Putaran 2: 30000 + 12000 = 42000. Hasil akhir = nilai $bawa terakhir. Tidak seperti array_sum, reduce bisa menghitung dari struktur nested apa pun.

php
<?php
// Contoh 2: akumulator tidak harus angka!
$kata = ["Saya", "belajar", "PHP"];

// Lebur jadi kalimat
$kalimat = array_reduce($kata, fn($bawa, $k) => $bawa . $k . " ", "");
echo trim($kalimat);   // "Saya belajar PHP"

// Lebur jadi HTML (pola rendering tabel)
$produk = [["Kopi", 15000], ["Roti", 12000]];
$html = array_reduce($produk, function ($bawa, $p) {
    return $bawa . "<tr><td>{$p[0]}</td><td>{$p[1]}</td></tr>";
}, "");
echo "<table>$html</table>";

// Lebur jadi statistik gabungan
$angka = [85, 92, 78, 90];
$stat = array_reduce($angka, function ($bawa, $n) {
    $bawa["total"] += $n;
    $bawa["count"]++;
    $bawa["max"] = max($bawa["max"], $n);
    return $bawa;
}, ["total" => 0, "count" => 0, "max" => 0]);
echo $stat["total"] / $stat["count"];   // rata-rata: 86.25

Akumulator boleh array, string, atau objek. Pola "statistik gabungan" menghitung total, count, dan max dalam satu putaran, efisien untuk data besar.

Jebakan yang Sering Terjadi

Lupa nilai awal. Tanpa argumen ketiga, $bawa mulai dari null dan putaran pertama memakai item pertama sebagai akumulator: hasilnya aneh untuk string/array. Selalu tulis nilai awal eksplisit (0, "", []).

Lupa me-return akumulator. Callback wajib return $bawa di akhir. Lupa return = $bawa menjadi null di putaran berikutnya dan hasil akhir hancur. Ini error paling umum di reduce.

Reduce untuk Validasi Agregat

Selain angka dan string, reduce hebat untuk pertanyaan "apakah semua...?" atau "ada yang...?":

php
<?php
$nilai = [85, 92, 78];

// Apakah SEMUA lulus (>= 75)?
$semuaLulus = array_reduce($nilai, fn($bawa, $n) => $bawa && $n >= 75, true);
var_dump($semuaLulus);   // true

// Apakah ADA yang sempurna (100)?
$adaSempurna = array_reduce($nilai, fn($bawa, $n) => $bawa || $n === 100, false);
var_dump($adaSempurna);   // false

// Kelompokkan berdasar predikat (group by manual)
$kelompok = array_reduce($nilai, function ($bawa, $n) {
    $kunci = $n >= 90 ? "A" : ($n >= 75 ? "B" : "C");
    $bawa[$kunci][] = $n;
    return $bawa;
}, []);
print_r($kelompok);   // ["B" => [85, 78], "A" => [92]]

Pola group-by ini adalah fondasi laporan: kelompokkan transaksi per bulan, siswa per kelas, produk per kategori, semua dengan satu reduce.

Catatan teknis: Tiga serangkai kini lengkap: map (1:1), filter (N:sebagian), reduce (N:1). Kombinasi ketiganya, misalnya array_reduce(array_filter(array_map(...))), menyelesaikan pipeline olah data tanpa satu pun loop manual.

Tantangan

Hitung omzet harian

Diberi array transaksi [["Kopi", 15000, 3], ["Teh", 8000, 5], ["Roti", 12000, 2]] (format: nama, harga, qty). Gunakan array_reduce untuk menghitung total omzet (harga x qty). Nilai awal akumulator 0.