The Power Of Array.reduce()🐐
Tags: javascript, webdev, beginners
Published: 2024-05-21 04:15:48

Hai, teman-teman developer! 👋

Pernah merasa bingung dengan bagaimana cara mengolah data di dalam array secara efisien? Nah, kali ini kita akan bahas salah satu metode JavaScript yang super keren dan sangat berguna: array.reduce! Metode ini bisa dibilang adalah pisau serbaguna dalam dunia pemrograman, karena memungkinkan kita untuk melakukan berbagai operasi kompleks dengan cara yang sederhana dan elegan.

Bayangkan kamu punya sekumpulan data dan ingin menghitung totalnya, mencari nilai maksimum, atau bahkan mengubah bentuk data menjadi struktur yang berbeda. Semua itu bisa kamu lakukan dengan reduce! Jadi, siap-siap untuk memperkaya toolkit coding kamu dengan pengetahuan baru ini. Yuk, kita mulai petualangan kita dengan memahami array.reduce dan melihat berbagai cara keren untuk menggunakannya! 🚀

8 Cara Keren Menggunakan `Array.reduce()` 🐐:

## Contoh Kasus 1: Menjumlahkan Angka
Salah satu penggunaan `reduce()` yang paling sederhana adalah untuk menjumlahkan sejumlah angka. Misalnya, kamu punya array berisi angka-angka dan ingin menemukan total jumlahnya.

```tsx
const numbers: number[] = [1, 2, 3, 4, 5];
const sum: number = numbers.reduce((acc, curr) => acc + curr, 0);
console.log(sum); // Output: 15
```

Boom!💣 Dengan hanya satu baris kode, kamu sudah menghitung jumlah semua elemen dalam array. Nilai awal accumulator (penyimpan sementara) kita set ke 0, dan di setiap iterasi, kita tambahkan elemen saat ini ke accumulator.

Bonus: Kalau kamu memilih untuk tidak menyertakan nilai awal, reduce akan menggunakan elemen pertama dalam array sebagai nilai awal. Tapi, biasanya saya selalu menyertakan nilai awal agar lebih mudah dibaca.

## Contoh Kasus 2: Meratakan Array

Pernahkah kamu mendapati dirimu memiliki array dari array dan berpikir, "Saya ingin meratakan ini menjadi satu array saja"?

```tsx
const nestedArray = [[1, 2], [3, 4], [5, 6]];
const flattenedArray = nestedArray.reduce((acc, curr) => acc.concat(curr), []);
console.log(flattenedArray); // Output: [1, 2, 3, 4, 5, 6]
```
Pada contoh ini, kita mulai dengan array kosong sebagai nilai awal accumulator. Kemudian, di setiap iterasi, kita menggabungkan sub-array saat ini ke accumulator menggunakan metode `concat()`. Pada akhirnya, kita memiliki array yang sudah rata sempurna.

saya tahu bahwa kamu juga bisa melakukan ini dengan `Array.flat()`. Namun, penting untuk tahu cara menggunakan reduce, jika kamu ingin melakukan operasi tambahan pada setiap item.

## Contoh Kasus 3: Mengelompokkan Objek

Bayangkan kamu memiliki array dari objek-objek, dan kamu ingin mengelompokkannya berdasarkan properti tertentu. `reduce()` adalah alat yang sempurna untuk pekerjaan ini.

```tsx
interface Person {
  name: string;
  age: number;
}

const people: Person[] = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 30 },
  { name: 'Charlie', age: 25 },
  { name: 'Dave', age: 30 }
];

const groupedByAge: { [key: number]: Person[] } = people.reduce((acc, curr) => {
  if (!acc[curr.age]) {
    acc[curr.age] = [];
  }
  acc[curr.age].push(curr);
  return acc;
}, {});

console.log(groupedByAge);
/*
Output:
{
  '25': [{ name: 'Alice', age: 25 }, { name: 'Charlie', age: 25 }],
  '30': [{ name: 'Bob', age: 30 }, { name: 'Dave', age: 30 }]
}
*/
```
Pada kasus ini, kita menggunakan objek sebagai nilai awal accumulator. Kita periksa apakah accumulator sudah memiliki properti untuk usia saat ini. Jika tidak, kita membuat array kosong untuk usia tersebut. Kemudian, kita memasukkan objek saat ini ke dalam array usia yang sesuai. Pada akhirnya, kita memiliki objek di mana kunci-kunci adalah usia, dan nilainya adalah array dari orang-orang dengan usia tersebut.

Sekarang kamu juga bisa mempelajari metode `groupBy` yang lebih baru. Namun, klasik ini yang sudah teruji dan terbukti penting untuk dipahami.

## Contoh Kasus 4: Membuat Lookup Maps

Salah satu favorit saya adalah menggunakan `reduce()` untuk membuat peta lookup dari array. Ini benar-benar meningkatkan performa dan keterbacaan kode. Tak perlu lagi menggunakan `find()` atau `filter()` yang lambat.

```tsx
interface Product {
  id: number;
  name: string;
  price: number;
}

const products: Product[] = [
  { id: 1, name: 'Laptop', price: 999 },
  { id: 2, name: 'Phone', price: 699 },
  { id: 3, name: 'Tablet', price: 499 },
];

const productMap: { [key: number]: Product } = products.reduce((acc, curr) => {
  acc[curr.id] = curr;
  return acc;
}, {});

console.log(productMap);
/*
Output:
{
  '1': { id: 1, name: 'Laptop', price: 999 },
  '2': { id: 2, name: 'Phone', price: 699 },
  '3': { id: 3, name: 'Tablet', price: 499 }
}
*/

// Accessing a product by ID
const laptop: Product = productMap[1];
console.log(laptop); // Output: { id: 1, name: 'Laptop', price: 999 }
```
Dengan menggunakan `reduce()` untuk membuat peta lookup, kamu bisa mengakses elemen berdasarkan identifier uniknya dengan kompleksitas waktu konstan. Tidak perlu lagi berulang kali melintasi array untuk menemukan item tertentu.

## Contoh Kasus 5: Menghitung Kemunculan Elemen

Oke untuk use case yang ke 5, teman teman pasti pernah butuh menghitung seberapa sering elemen muncul di dalam array? Tenang, `reduce()` bisa diandalkan untuk urusan ini.

```tsx
const fruits: string[] = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'];

const fruitCounts: { [key: string]: number } = fruits.reduce((acc, curr) => {
  acc[curr] = (acc[curr] || 0) + 1;
  return acc;
}, {});

console.log(fruitCounts);
/*
Output:
{
  'apple': 3,
  'banana': 2,
  'orange': 1
}
*/
```
Pada contoh ini, kita memulai dengan objek kosong sebagai accumulator. Untuk setiap buah dalam array, kita periksa apakah buah tersebut sudah ada sebagai properti di objek accumulator. Jika sudah, kita tambahkan jumlahnya dengan 1; jika belum, kita inisialisasi dengan 1. Hasil akhirnya adalah sebuah objek yang memberi tahu kita berapa kali setiap buah muncul dalam array.

## Contoh Kasus 6: Menyusun Fungsi

Buat kamu yang suka pemrograman fungsional, ini pasti menarik! `reduce()` adalah alat ampuh untuk menyusun fungsi. Kamu bisa bikin rangkaian fungsi yang mengubah data langkah demi langkah dengan mudah.

```tsx
const add5 = (x: number): number => x + 5;
const multiply3 = (x: number): number => x * 3;
const subtract2 = (x: number): number => x - 2;

const composedFunctions: ((x: number) => number)[] = [add5, multiply3, subtract2];

const result: number = composedFunctions.reduce((acc, curr) => curr(acc), 10);
console.log(result); // Output: 43
```
Dalam contoh ini, kita punya array berisi fungsi-fungsi yang ingin kita terapkan secara berurutan pada nilai awal 10. Kita menggunakan `reduce()` untuk mengiterasi fungsi-fungsi tersebut, dan setiap hasil dari fungsi sebelumnya menjadi input untuk fungsi berikutnya. Hasil akhirnya adalah output dari semua fungsi yang diterapkan secara berurutan.

## Contoh Kasus 7: Menghasilkan Nilai Unik

Kadang-kadang, kamu mungkin punya array dengan nilai-nilai yang duplikat, dan kamu perlu mengekstrak hanya yang unik. `reduce()` bisa membantu kamu melakukannya dengan mudah.

```tsx
const numbers: number[] = [1, 2, 3, 2, 4, 3, 5, 1, 6];

const uniqueNumbers: number[] = numbers.reduce((acc, curr) => {
  if (!acc.includes(curr)) {
    acc.push(curr);
  }
  return acc;
}, []);

console.log(uniqueNumbers); // Output: [1, 2, 3, 4, 5, 6]
```
Di sini, kita memulai dengan array kosong sebagai accumulator. Untuk setiap angka dalam array asli, kita periksa apakah angka tersebut sudah ada di accumulator menggunakan metode `includes()`. Jika belum ada, kita tambahkan ke dalam array accumulator. Hasil akhirnya adalah array yang hanya berisi nilai-nilai unik dari array asli.

## Use Case 8: Calculating Average
And the last one mau menghitung rata-rata dari sekumpulan angka? Tenang, `reduce()` bisa diandalkan!

```tsx
const grades: number[] = [85, 90, 92, 88, 95];

const average: number = grades.reduce((acc, curr, index, array) => {
  acc += curr;
  if (index === array.length - 1) {
    return acc / array.length;
  }
  return acc;
}, 0);

console.log(average); // Output: 90
```
Pada contoh ini, kita memulai accumulator dengan nilai 0. Kita iterasi setiap nilai dan menambahkannya ke accumulator. Saat mencapai elemen terakhir (diperiksa menggunakan indeks dan array.length), kita bagi nilai accumulator dengan jumlah total nilai untuk menghitung rata-ratanya.

## Pertimbangan Kinerja 🏎️

Meskipun `Array.reduce()` sangat kuat dan serbaguna, penting untuk menyadari kemungkinan keterbatasan kinerja, terutama saat berurusan dengan array besar atau operasi yang kompleks. Salah satu jebakan umum adalah membuat objek atau array baru di setiap iterasi `reduce()`, yang dapat menyebabkan alokasi memori berlebihan dan memengaruhi kinerja.

Sebagai contoh, pertimbangkan kode berikut:

```tsx
const numbers: number[] = [1, 2, 3, 4, 5];

const doubledNumbers: number[] = numbers.reduce((acc, curr) => {
  return [...acc, curr * 2];
}, []);

console.log(doubledNumbers); // Output: [2, 4, 6, 8, 10]
```
Dalam kasus ini, kita menggunakan operator spread (...) untuk membuat array baru di setiap iterasi, yang bisa menjadi tidak efisien. Sebagai gantinya, kita bisa mengoptimalkan kode dengan memutasi array accumulator secara langsung:

```tsx
const numbers: number[] = [1, 2, 3, 4, 5];

const doubledNumbers: number[] = numbers.reduce((acc, curr) => {
  acc.push(curr * 2);
  return acc;
}, []);

console.log(doubledNumbers); // Output: [2, 4, 6, 8, 10]
```
Dengan memutasi array accumulator menggunakan `push()`, kita menghindari pembuatan array baru di setiap iterasi, yang menghasilkan kinerja yang lebih baik.

Demikian pula, saat bekerja dengan objek, lebih efisien untuk memutasi objek accumulator secara langsung daripada membuat objek baru dengan operator spread:

```tsx
const people: Person[] = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 30 },
  { name: 'Charlie', age: 25 },
  { name: 'Dave', age: 30 }
];

const groupedByAge: { [key: number]: Person[] } = people.reduce((acc, curr) => {
  if (!acc[curr.age]) {
    acc[curr.age] = [];
  }
  acc[curr.age].push(curr);
  return acc;
}, {});
```
Dengan memutasi objek accumulator secara langsung, kita mengoptimalkan kinerja operasi `reduce()`.

Namun, perlu dicatat bahwa dalam beberapa kasus, pembuatan objek atau array baru di setiap iterasi mungkin diperlukan atau lebih mudah dibaca. Penting untuk menemukan keseimbangan antara kinerja dan kejelasan kode berdasarkan kasus penggunaan spesifik Anda dan ukuran data yang sedang Anda kerjakan.

## Kesimpulan

Nah, itulah delapan contoh penggunaan yang luar biasa yang menunjukkan kekuatan dan fleksibilitas dari `Array.reduce()`. Mulai dari menjumlahkan angka hingga meratakan array, mengelompokkan objek hingga membuat peta lookup, menghitung kemunculan hingga menyusun fungsi, dan menghitung rata-rata, `Array.reduce()` terbukti menjadi alat yang kuat dalam toolkit JavaScript kamu.

Bagaimana menurutmu? Metode array favoritmu apa, dan mengapa?

Terima kasih sudah membaca, dan sampai jumpa pada postingan selanjutnya, Stay tuned, guys!. ✨🐐✨