`Array` objek
Artikel ini menjelaskan tentang objek Array.
Saya akan menjelaskan penggunaan praktis array secara bertahap dengan cara yang mudah dipahami.
YouTube Video
Array objek
Objek Array pada JavaScript adalah salah satu struktur terpenting yang menjadi dasar dari berbagai pemrosesan data. Dari operasi array dasar hingga fungsi tingkat tinggi yang berguna untuk transformasi data yang efisien, ada banyak fitur yang perlu Anda ketahui.
Dasar-dasar Array
Dalam JavaScript, array adalah struktur data mendasar untuk menangani banyak nilai sekaligus. Di sini, kami memperkenalkan cara membuat array serta cara membaca dan menulis elemennya dengan contoh sederhana.
1// Create arrays in different ways
2const arr1 = [1, 2, 3]; // array literal
3const arr2 = new Array(4, 5, 6); // Array constructor
4const arr3 = Array.of(7, 8, 9); // Array.of
5
6console.log("arr1 created with literal. :", arr1);
7console.log("arr2 created with constructor:", arr2);
8console.log("arr3 created with Array.of. :", arr3);
9// arr1 created with literal. : [ 1, 2, 3 ]
10// arr2 created with constructor: [ 4, 5, 6 ]
11// arr3 created with Array.of. : [ 7, 8, 9 ]
12
13// Access and modify elements
14let first = arr1[0]; // read element
15console.log("First element of arr1:", first);
16// First element of arr1: 1
17
18arr1[1] = 20; // modify element
19console.log("arr1 after modifying index 1:", arr1);
20// arr1 after modifying index 1: [ 1, 20, 3 ]
21
22const len = arr1.length; // get length
23console.log("Length of arr1:", len);
24// Length of arr1: 3
- Kode ini menunjukkan tiga cara untuk membuat array, cara membaca dan memperbarui elemen menggunakan indeks, dan cara mendapatkan panjang array dengan properti
length. - Literal array adalah yang paling umum dan mudah dibaca, serta paling sering digunakan dalam situasi sehari-hari.
Menambahkan dan Menghapus Elemen (di Akhir atau Awal)
Array memungkinkan Anda menambah atau menghapus elemen dengan mudah di bagian akhir atau awal. Operasi-operasi ini juga berguna saat menerapkan struktur seperti stack atau queue.
1// Push and pop (stack-like)
2const stack = [];
3console.log("Initial stack:", stack);
4
5stack.push(1); // push 1
6console.log("After push(1):", stack);
7
8stack.push(2); // push 2
9console.log("After push(2):", stack);
10
11const last = stack.pop(); // pop -> 2
12console.log("Popped value:", last);
13console.log("Stack after pop():", stack);
14
15// Unshift and shift (queue-like)
16const queue = [];
17console.log("Initial queue:", queue);
18
19queue.push('a'); // add to end
20console.log("After push('a'):", queue);
21
22queue.unshift('start'); // add to front
23console.log("After unshift('start'):", queue);
24
25const firstItem = queue.shift(); // remove from front
26console.log("Shifted value:", firstItem);
27console.log("Queue after shift():", queue);
28
29// Initial stack: []
30// After push(1): [ 1 ]
31// After push(2): [ 1, 2 ]
32// Popped value: 2
33// Stack after pop(): [ 1 ]
34
35// Initial queue: []
36// After push('a'): [ 'a' ]
37// After unshift('start'): [ 'start', 'a' ]
38// Shifted value: start
39// Queue after shift(): [ 'a' ]
pushdanpopberoperasi pada akhir array. Mereka sangat ideal untuk menerapkan struktur stack.unshiftdanshiftberoperasi pada awal array. Namun, perlu diperhatikan bahwa operasi di awal array memerlukan pergeseran semua indeks elemen secara internal, sehingga operasinya cukup mahal.
Menangani Elemen di Tengah (splice dan slice)
Saat menangani elemen di tengah array, pilih antara splice dan slice tergantung apakah Anda ingin memodifikasi array asli atau tidak. Jika Anda hanya ingin mengekstrak sebagian dari array, gunakan slice; jika Anda ingin memodifikasi array itu sendiri, seperti menyisipkan atau menghapus elemen, gunakan splice.
1// slice (non-destructive)
2const nums = [0, 1, 2, 3, 4];
3console.log("Original nums:", nums);
4
5const part = nums.slice(1, 4); // returns [1, 2, 3]
6console.log("Result of nums.slice(1, 4):", part);
7console.log("nums after slice (unchanged):", nums);
8
9// splice (destructive)
10const arr = [10, 20, 30, 40];
11console.log("\nOriginal arr:", arr);
12
13// remove 1 item at index 2, insert 25 and 27
14arr.splice(2, 1, 25, 27);
15console.log("After arr.splice(2, 1, 25, 27):", arr);
16
17// Original nums: [ 0, 1, 2, 3, 4 ]
18// Result of nums.slice(1, 4): [ 1, 2, 3 ]
19// nums after slice (unchanged): [ 0, 1, 2, 3, 4 ]
20
21// Original arr: [ 10, 20, 30, 40 ]
22// After arr.splice(2, 1, 25, 27): [ 10, 20, 25, 27, 40 ]
slicehanya mengekstrak elemen dan tidak memodifikasi array asli.splicemenambah atau menghapus elemen serta memodifikasi array itu sendiri, jadi berhati-hatilah terhadap dampaknya pada perilaku array.
Iterasi (for / for...of / forEach)
Ada beberapa cara untuk memproses array secara berurutan, dan Anda dapat memilih sesuai tujuan dan preferensi gaya penulisan kode. Berikut adalah tiga konstruksi loop yang umum.
1const items = ['apple', 'banana', 'cherry'];
2console.log("Items:", items);
3
4// classic for
5console.log("\n--- Classic for loop ---");
6for (let i = 0; i < items.length; i++) {
7 console.log(`Index: ${i}, Value: ${items[i]}`);
8}
9
10// for...of (recommended for values)
11console.log("\n--- for...of loop ---");
12for (const item of items) {
13 console.log(`Value: ${item}`);
14}
15
16// forEach (functional style)
17console.log("\n--- forEach loop ---");
18items.forEach((item, index) => {
19 console.log(`Index: ${index}, Value: ${item}`);
20});forloop adalah yang paling fleksibel, memungkinkan operasi indeks dan kontrol iterasi yang detail menggunakanbreakdan statement lainnya.for...ofmenyediakan cara ringkas dalam menangani nilai elemen dan paling seimbang dalam hal keterbacaan.forEachmemungkinkan penulisan kode bergaya fungsional dan sangat cocok untuk operasi dengan efek samping, seperti pencatatan log atau memperbarui data setiap elemen. Namun, perhatikan bahwa Anda tidak dapat menggunakanbreakataucontinue, dan tidak cocok untuk pemrosesan asinkron denganawait.
map / filter / reduce — Fungsi Tingkat Tinggi
map, filter, dan reduce adalah fungsi tingkat tinggi yang sering digunakan saat mentransformasikan, memfilter, atau mengagregasi array. Karena Anda dapat dengan jelas mengekspresikan proses berulang, kode Anda menjadi sederhana dan mudah dipahami.
1const numbers = [1, 2, 3, 4, 5];
2console.log("Original numbers:", numbers);
3
4// map: transform each item
5const doubled = numbers.map(n => n * 2);
6console.log("\nResult of map (n * 2):", doubled);
7
8// filter: select items
9const evens = numbers.filter(n => n % 2 === 0);
10console.log("Result of filter (even numbers):", evens);
11
12// reduce: accumulate to single value
13const sum = numbers.reduce((acc, n) => acc + n, 0);
14console.log("Result of reduce (sum):", sum);
15
16// Original numbers: [ 1, 2, 3, 4, 5 ]
17// Result of map (n * 2): [ 2, 4, 6, 8, 10 ]
18// Result of filter (even numbers): [ 2, 4 ]
19// Result of reduce (sum): 15
- Metode-metode ini memungkinkan Anda fokus pada apa yang ingin dilakukan dengan gaya deklaratif, meningkatkan keterbacaan dan membantu menghindari efek samping yang tidak diinginkan.
find / findIndex / some / every
Berikut adalah gambaran tentang metode pencarian dan pemeriksaan kondisi. Ini berguna untuk menemukan elemen yang memenuhi syarat tertentu atau melakukan pemeriksaan boolean pada sekumpulan data.
1const users = [
2 { id: 1, name: 'Alice' },
3 { id: 2, name: 'Bob' },
4 { id: 3, name: 'Carol' }
5];
6
7console.log("Users:", users);
8
9// Find the first user whose name is 'Bob'
10const bob = users.find(user => user.name === 'Bob');
11console.log("\nResult of find (name === 'Bob'):", bob);
12
13// Find index of the user whose id is 3
14const indexOfId3 = users.findIndex(user => user.id === 3);
15console.log("Result of findIndex (id === 3):", indexOfId3);
16
17// Check if there exists a user with id = 2
18const hasId2 = users.some(user => user.id === 2);
19console.log("Result of some (id === 2):", hasId2);
20
21// Check if all users have a numeric id
22const allHaveNumericId = users.every(user => typeof user.id === 'number');
23console.log("Result of every (id is number):", allHaveNumericId);
24// Result of find (name === 'Bob'): { id: 2, name: 'Bob' }
25// Result of findIndex (id === 3): 2
26// Result of some (id === 2): true
27// Result of every (id is number): true
findmengembalikan elemen pertama yang memenuhi kondisi.findIndexmengembalikan indeks dari elemen yang memenuhi kondisi.somemengembalikantruejika ada setidaknya satu elemen yang memenuhi kondisi.everymengembalikantruejika semua elemen memenuhi kondisi.
Semua ini sangat berguna dalam pemrosesan array, jadi gunakan sesuai kebutuhan agar kode Anda tetap ringkas dan jelas.
Fungsi Pengurutan dan Perbandingan
Array diurutkan menggunakan sort, namun secara default membandingkan elemen sebagai string, yang bisa menghasilkan hasil tak terduga saat mengurutkan angka.
1const nums = [10, 2, 33, 4];
2console.log("Original nums:", nums);
3
4// Default sort: compares elements as strings (not suitable for numbers)
5nums.sort();
6console.log("\nAfter default sort (string comparison):", nums);
7
8// Numeric ascending sort using a compare function
9nums.sort((a, b) => a - b);
10console.log("After numeric sort (a - b):", nums);
11
12// Sort objects by a property
13const people = [{ age: 30 }, { age: 20 }, { age: 25 }];
14console.log("\nOriginal people:", people);
15
16people.sort((a, b) => a.age - b.age);
17console.log("After sorting people by age:", people);
18
19// After default sort (string comparison): [ 10, 2, 33, 4 ]
20// After numeric sort (a - b): [ 2, 4, 10, 33 ]
21// Original people: [ { age: 30 }, { age: 20 }, { age: 25 } ]
22// After sorting people by age: [ { age: 20 }, { age: 25 }, { age: 30 } ]
- Saat mengurutkan angka atau objek, selalu tentukan fungsi perbandingan untuk mendapatkan urutan yang sesuai.
- Dalam fungsi perbandingan, nilai kembali negatif menempatkan
adi depanb, positif menempatkanbdi depana, dan 0 mempertahankan urutan tetap.
Penyalinan Array dan Imutabilitas
Saat menyalin array, penting untuk memahami perbedaan antara 'salinan referensi' dan 'salinan dangkal.'. Terutama, perhatikan bahwa jika ada objek di dalam array, salinan dangkal akan menyebabkan objek di dalamnya tetap dibagi bersama.
Salinan referensi
Ketika Anda menetapkan array ke variabel lain, array itu sendiri tidak diduplikasi; sebaliknya, 'referensi' yang menunjuk ke array yang sama disalin.
1const a = [1, 2, 3];
2console.log("Original a:", a);
3
4// Reference copy; modifying b also affects a
5const b = a;
6console.log("\nReference copy b = a:", b);
7// Reference copy b = a: [ 1, 2, 3 ]
8
9b[0] = 100;
10console.log("After modifying b[0] = 100:");
11console.log("a:", a); // a: [ 100, 2, 3 ] (affected)
12console.log("b:", b); // b: [ 100, 2, 3 ]
- Dengan salinan referensi, jika Anda memodifikasi isi array menggunakan variabel salinan, perubahan tersebut juga akan tercermin di variabel asli yang merujuk pada array yang sama.
Salinan dangkal
Menggunakan slice() atau sintaks spread menciptakan 'salinan dangkal' karena hanya nilainya yang diduplikasi; array asli dan hasil salinan diperlakukan sebagai entitas terpisah.
1const a = [1, 2, 3];
2console.log("Original a:", a);
3
4// Shallow copy (new array)
5const b = a.slice();
6console.log("\nShallow copy using slice():", b);
7// Shallow copy using slice(): [ 100, 2, 3 ]
8
9const c = [...a];
10console.log("Shallow copy using spread [...a]:", c);
11// Shallow copy using spread [...a]: [ 100, 2, 3 ]
12
13// Modifying c or d does NOT affect a
14b[1] = 200;
15c[2] = 300;
16console.log("\nAfter modifying b[1] = 200 and c[2] = 300:");
17console.log("a:", a); // [ 100, 2, 3 ]
18console.log("b:", b); // [ 100, 200, 3 ]
19console.log("c:", c); // [ 100, 2, 300 ]
- Kode ini menunjukkan bahwa salinan dangkal dari array yang dibuat oleh
slice()atau sintaks spread tidak memengaruhi array aslinya.
Salinan dangkal dan imutabilitas
Bahkan jika Anda menduplikasi array menggunakan 'salinan dangkal', pembagian yang tidak disengaja dapat terjadi jika array tersebut berisi objek di dalamnya.
1// Shallow copy doesn't clone inner objects
2const nested = [{ x: 1 }, { x: 2 }];
3console.log("\nOriginal nested:", nested);
4// Original nested: [ { x: 1 }, { x: 2 } ]
5
6const shallow = nested.slice();
7console.log("Shallow copy of nested:", shallow);
8// Shallow copy of nested: [ { x: 1 }, { x: 2 } ]
9
10// Changing inner object affects both arrays
11shallow[0].x = 99;
12console.log("\nAfter shallow[0].x = 99:");
13console.log("nested:", nested);
14console.log("shallow:", shallow);
15// nested: [ { x: 99 }, { x: 2 } ]
16// shallow: [ { x: 99 }, { x: 2 } ]
- Kode ini menunjukkan bahwa dengan salinan dangkal, objek di dalamnya masih dibagikan, sehingga memodifikasi objek tersebut akan memengaruhi kedua array, baik asli maupun hasil salinan.
- Jika Anda membutuhkan data yang benar-benar mandiri, Anda memerlukan 'salinan penuh' seperti menggunakan
structuredClone()atau konversi JSON.
Metode utilitas yang berguna
Berikut ini adalah metode utilitas yang sering digunakan saat bekerja dengan array. Dengan menggunakannya secara tepat sesuai tujuan, Anda bisa menulis kode yang singkat dan mudah dibaca.
includes
Metode includes memeriksa apakah suatu nilai tertentu terdapat di dalam array.
1// includes: check if array contains a value
2const letters = ['a', 'b', 'c'];
3const hasB = letters.includes('b');
4console.log("letters:", letters); // [ 'a', 'b', 'c' ]
5console.log("letters.includes('b'):", hasB); // true
- Pada kode ini, metode
includesdigunakan untuk menentukan dengan singkat apakah suatu nilai tertentu ada di dalam array.
concat
Metode concat mengembalikan array baru yang menambahkan array atau nilai yang ditentukan ke bagian akhir, sementara array aslinya tetap tidak berubah.
1// concat: merge arrays without mutation
2const a1 = [1, 2];
3const a2 = [3, 4];
4const combined = a1.concat(a2);
5console.log("a1.concat(a2):", combined); // [ 1, 2, 3, 4 ]
6console.log("a1(unchanged):", a1); // [ 1, 2 ]
- Kode ini menunjukkan bahwa
concatbersifat non-destruktif, memungkinkan Anda membuat array baru tanpa mengubah array aslinya.
flat
Dengan menggunakan metode flat, Anda dapat meratakan array bersarang.
1// flat and flatMap: flatten arrays or map + flatten in one step
2const nested = [1, [2, [3]]];
3console.log("nested:", nested); // nested: [ 1, [ 2, [ 3 ] ] ]
4console.log("nested.flat():", nested.flat()); // default depth = 1
5// nested.flat(): [ 1, 2, [ 3 ] ]
- Kode ini menunjukkan hasil dari meratakan sebuah array hingga satu tingkat.
- Karena
flatmemungkinkan Anda menentukan kedalaman, Anda dapat mengatasi tingkat bersarang sesuai kebutuhan dengan lebih fleksibel.
flatMap
Metode flatMap menerapkan transformasi ke setiap elemen lalu secara otomatis meratakan hasilnya menjadi array satu dimensi.
1// flat and flatMap: flatten arrays or map + flatten in one step
2const words = ['hello world', 'hi'];
3console.log("words:", words); // [ 'hello world', 'hi' ]
4
5const splitWords = words.flatMap(w => w.split(' '));
6console.log("words.flatMap(w => w.split(' ')):", splitWords);
7// words.flatMap(w => w.split(' ')): [ 'hello', 'world', 'hi' ]
- Kode ini memperlihatkan contoh di mana setiap string dalam array dipecah berdasarkan spasi, lalu hasilnya digabungkan dan diratakan menjadi satu array.
join
Metode join membuat string dengan menggabungkan elemen-elemen array menggunakan pemisah tertentu.
1// join: combine elements into a string with a separator
2const csv = ['a', 'b', 'c'].join(',');
3console.log("['a', 'b', 'c'].join(','):", csv); // a,b,c
- Pada kode ini, metode
joindigunakan untuk mengubah array menjadi string terpisah koma.
Kesalahan Umum
Operasi pada array mungkin terlihat sederhana pada pandangan pertama, tetapi ada beberapa hal yang dapat menyebabkan perilaku tak terduga. Banyak kesalahan mudah terlewatkan dalam operasi array sehari-hari, jadi mengingat hal-hal berikut akan sangat meningkatkan keandalan kode Anda.
sort()padaArraysecara default mengurutkan berdasarkan perbandingan string. Untuk mengurutkan angka dengan benar, Anda harus selalu menyediakan fungsi perbandingan.- Menyalin array (menggunakan
sliceatau spread syntax, dll.) akan membuat salinan dangkal. Jika array Anda berisi objek, berhati-hatilah karena data asli bisa saja berubah tanpa sengaja. spliceadalah metode destruktif yang langsung mengubah array, sedangkansliceadalah metode tidak destruktif yang tidak memodifikasi array asli. Penting untuk menggunakannya secara tepat sesuai kebutuhan Anda.forEachtidak cocok untuk loop dengan pemrosesan asinkron menggunakanawait. Jika Anda ingin menjalankan pemrosesan asinkron secara berurutan dengan andal, disarankan menggunakanfor...of.
Contoh Praktis
Berikut adalah contoh yang menggabungkan metode array untuk 'mengambil total umur dari data pengguna, mengekstrak mereka yang berusia 30 tahun ke atas, dan membuat daftar nama.'.
1const users = [
2 { name: 'Alice', age: 28 },
3 { name: 'Bob', age: 34 },
4 { name: 'Carol', age: 41 },
5 { name: 'Dave', age: 19 }
6];
7
8console.log("Users:", users);
9
10// sum ages
11const totalAge = users.reduce((acc, u) => acc + u.age, 0);
12console.log("\nTotal age of all users:", totalAge);
13// Total age of all users: 122
14
15// filter and map names of users 30 and older
16const namesOver30 = users
17 .filter(u => u.age >= 30)
18 .map(u => u.name);
19
20console.log("Users aged 30 or older (names):", namesOver30);
21// Users aged 30 or older (names): [ 'Bob', 'Carol' ]
- Dengan menggabungkan
reduce,filter, danmap, Anda dapat menulis agregasi, ekstraksi kondisi, dan transformasi data dengan sederhana. - Pola 'data processing pipeline' seperti ini sangat mudah dibaca dan, karena minim efek samping, sering dipakai di aplikasi dunia nyata.
Ringkasan
Dengan array JavaScript, operasi dasar pun sangat luas aplikasinya, dan dengan menggunakan fungsi tingkat tinggi, kode Anda akan menjadi lebih ringkas dan ekspresif. Ada banyak poin yang perlu dipahami, tetapi begitu Anda menguasai penggunaannya secara tepat, pemrosesan data akan menjadi jauh lebih lancar.
Anda dapat mengikuti artikel di atas menggunakan Visual Studio Code di saluran YouTube kami. Silakan periksa juga saluran YouTube kami.