Masukkan Password
82 Metode Array Non-destruktif
Lecture ini sebenarnya memperkenalkan dua kelompok konsep penting:
Method Array baru di ES2023 yang merupakan versi non-destructive dari:
sort()→toSorted()reverse()→toReversed()splice()→toSpliced()
Method Array baru di ES2022:
findLast()findLastIndex()
Kuncinya adalah memahami perbedaan:
METHOD LAMA
→ mengubah Array asli
METHOD BARU
→ tidak mengubah Array asli
→ membuat Array baru
Mari kita bahas pelan-pelan.
1. Apa maksud “destructive” dan “non-destructive”?
Istilah ini penting.
Destructive / mutating
Artinya method tersebut mengubah data asli.
Contoh:
let names = ["John", "Mark", "Arun"];
names.reverse();
console.log(names);
Hasil:
["Arun", "Mark", "John"]
Array names berubah.
Non-destructive
Artinya:
Operasi dilakukan untuk menghasilkan data baru, tetapi data asli tetap dipertahankan.
Contoh:
let names = ["John", "Mark", "Arun"];
let reversed = names.toReversed();
console.log(names);
console.log(reversed);
Hasil:
names:
["John", "Mark", "Arun"]
reversed:
["Arun", "Mark", "John"]
Jadi:
names ───────────────→ tetap
names.toReversed()
↓
Array baru
2. Kenapa kita membutuhkan versi non-destructive?
Ini sangat penting dalam project nyata.
Misalnya kita mempunyai:
let movies = [
{ name: "Movie A", rating: 4.5 },
{ name: "Movie B", rating: 3.2 },
{ name: "Movie C", rating: 4.8 }
];
Kemudian kita ingin menampilkan:
Movie berdasarkan rating tertinggi.
Kalau kita menggunakan:
movies.sort((a, b) => b.rating - a.rating);
movies asli ikut berubah.
Kadang itu tidak kita inginkan.
Misalnya kita ingin:
movies asli
↓
tetap dengan urutan awal
+
sortedMovies
↓
versi yang sudah diurutkan
Maka method seperti toSorted() sangat berguna.
3. Cara lama: slice() + sort()
Sebelum ES2023, salah satu cara yang umum adalah membuat copy terlebih dahulu.
Misalnya:
let names = ["John", "Mark", "Arun"];
let copy = names.slice();
copy.sort();
Hasil:
names
["John", "Mark", "Arun"]
copy
["Arun", "John", "Mark"]
names tetap.
Kenapa?
Karena:
names.slice()
membuat Array baru.
Kemudian:
copy.sort()
hanya mengubah copy.
4. ES2023 membuatnya lebih mudah
Sekarang kita punya:
let sorted = names.toSorted();
Tidak perlu:
let copy = names.slice();
copy.sort();
Jadi:
CARA LAMA
names
↓
slice()
↓
copy
↓
sort()
↓
sorted copy
CARA BARU
names
↓
toSorted()
↓
sorted copy
Lebih ringkas dan maksud kodenya lebih jelas.
5. toSorted()
toSorted() adalah versi non-destructive dari sort().
sort()
let numbers = [3, 1, 2];
numbers.sort();
console.log(numbers);
Hasil:
[1, 2, 3]
numbers berubah.
toSorted()
let numbers = [3, 1, 2];
let sortedNumbers = numbers.toSorted();
console.log(numbers);
console.log(sortedNumbers);
Hasil:
numbers:
[3, 1, 2]
sortedNumbers:
[1, 2, 3]
Jadi:
sort()
→ ubah Array asli
toSorted()
→ buat Array baru
6. toSorted() tetap menerima comparator
Ini penting.
Kamu sudah belajar:
movies.sort((a, b) => {
return a.rating - b.rating;
});
Untuk toSorted() caranya hampir sama:
let sortedMovies = movies.toSorted((a, b) => {
return a.rating - b.rating;
});
Hasilnya:
movies
↓
tetap seperti semula
toSorted()
↓
Array baru
↓
diurutkan berdasarkan rating
Jadi kamu tidak perlu mempelajari aturan sorting baru.
7. sort() vs toSorted()
| Method | Mengubah Array asli? | Menghasilkan Array baru? |
|---|---|---|
sort() | ✅ | ❌ |
toSorted() | ❌ | ✅ |
Mental model:
sort()
→ "Urutkan SAYA"
toSorted()
→ "Buatkan versi terurut dari SAYA"
8. toReversed()
Sekarang pasangan kedua:
reverse()
↓
toReversed()
reverse() membalik Array dan mengubah Array asli.
Contoh:
let names = ["John", "Mark", "Arun"];
names.reverse();
console.log(names);
Hasil:
["Arun", "Mark", "John"]
9. toReversed() tidak mengubah Array asli
let names = ["John", "Mark", "Arun"];
let reversed = names.toReversed();
console.log(names);
console.log(reversed);
Hasil:
names:
["John", "Mark", "Arun"]
reversed:
["Arun", "Mark", "John"]
Jadi:
reverse()
→ balik Array asli
toReversed()
→ buat Array baru yang urutannya dibalik
10. Visualisasi toReversed()
Misalnya:
["A", "B", "C", "D"]
Diproses:
.toReversed()
menjadi:
Original:
[A][B][C][D]
↓
New Array:
[D][C][B][A]
Original tetap:
[A][B][C][D]
11. toSpliced()
Pasangan ketiga:
splice()
↓
toSpliced()
Kamu sudah belajar bahwa:
splice()
bisa digunakan untuk menghapus atau mengganti element Array.
Misalnya:
let names = ["John", "Mark", "Arun", "Steve"];
names.splice(1, 2);
Artinya:
mulai index 1
hapus 2 element
Index:
0 1 2 3
John Mark Arun Steve
↑ ↑
hapus hapus
Hasil names:
["John", "Steve"]
Array asli berubah.
12. toSpliced() melakukan operasi yang sama tanpa mengubah original
let names = ["John", "Mark", "Arun", "Steve"];
let newNames = names.toSpliced(1, 2);
Hasil:
names:
["John", "Mark", "Arun", "Steve"]
newNames:
["John", "Steve"]
Jadi:
splice()
→ ubah original
toSpliced()
→ buat Array baru
13. toSpliced() juga bisa mengganti element
Ingat splice() bukan hanya untuk delete.
Misalnya:
let names = ["John", "Mark", "Arun"];
Kita bisa:
let updated = names.toSpliced(1, 1, "David");
Artinya:
mulai index 1
hapus 1
masukkan "David"
Hasil:
updated
// ["John", "David", "Arun"]
Sedangkan:
names
tetap:
["John", "Mark", "Arun"]
14. Tiga method ES2023
Sekarang kita punya pasangan:
LAMA BARU
──────────────────────────────
sort() → toSorted()
reverse() → toReversed()
splice() → toSpliced()
Dan perbedaannya:
sort()
reverse()
splice()
↓
MUTATE original Array
toSorted()
toReversed()
toSpliced()
↓
TIDAK mutate original
↓
RETURN Array baru
15. Cara mudah mengingatnya
Perhatikan awalan:
toSorted
toReversed
toSpliced
Kata to bisa kamu jadikan pengingat:
“Buat hasil baru menuju bentuk tersebut.”
Bukan aturan bahasa resmi tentang arti kata to, tetapi sebagai mnemonic sangat membantu.
sort → ubah dirinya
toSorted → buat versi sorted
reverse → ubah dirinya
toReversed → buat versi reversed
splice → ubah dirinya
toSpliced → buat versi hasil splice
16. Ini sangat relevan dengan project CIN kamu
Misalnya sebelumnya kamu punya:
let movies = [...];
Untuk sorting rating, kamu sebelumnya belajar:
movies.sort((current, next) => {
return current.rating - next.rating;
});
Masalahnya:
movies
↓
sort()
↓
movies ikut berubah
Dengan ES2023:
let sortedMovies = movies.toSorted((current, next) => {
return current.rating - next.rating;
});
Sekarang:
movies
↓
tetap original
toSorted()
↓
sortedMovies
Ini sangat berguna jika project membutuhkan data original + beberapa versi tampilan.
17. Sekarang masuk ES2022: findLast()
Lecture kemudian berpindah ke dua method yang diperkenalkan di ES2022:
findLast()
findLastIndex()
Ini sangat mudah kalau kamu sudah memahami:
find()
findIndex()
18. Ingat find()
Misalnya:
let names = [
"John",
"Mark",
"Arun",
"Steve"
];
Kita ingin mencari nama pertama yang panjangnya 4 karakter:
let result = names.find((name) => {
return name.length === 4;
});
Hasil:
"John"
Kenapa?
Kita cek satu per satu:
John → length 4 → ✅
Karena sudah menemukan yang cocok, find() berhenti.
John
↓
MATCH!
↓
return "John"
↓
STOP
19. find() mencari dari depan
Secara sederhana:
→ → → → →
Misalnya:
["John", "Mark", "Arun", "Steve"]
find() mencari:
John
↓
Mark
↓
Arun
↓
Steve
dan mengembalikan yang pertama cocok.
20. findLast() mencari dari belakang
Sekarang:
let result = names.findLast((name) => {
return name.length === 4;
});
Pencarian dilakukan dari belakang:
Steve
↓
Arun
↓
Mark
↓
John
Misalnya semuanya memiliki kondisi yang cocok, findLast() akan mengambil yang paling terakhir dalam Array.
21. Contoh yang lebih jelas
Gunakan:
let names = [
"John",
"Mark",
"Arun",
"David",
"Peter"
];
Cari nama dengan panjang 4.
Yang cocok:
John → 4 ✅
Mark → 4 ✅
Arun → 4 ✅
David → 5 ❌
Peter → 5 ❌
find()
Mengambil yang pertama:
names.find(name => name.length === 4);
Hasil:
"John"
findLast()
Mengambil yang terakhir:
names.findLast(name => name.length === 4);
Hasil:
"Arun"
Visual:
Array:
John → Mark → Arun → David → Peter
↑ ↑
| |
find() findLast()
yang pertama yang terakhir
yang cocok yang cocok
22. find() vs findLast()
| Method | Mulai mencari dari | Hasil |
|---|---|---|
find() | depan | element pertama yang cocok |
findLast() | belakang | element terakhir yang cocok |
Mental model:
find()
→ "Cari yang pertama"
findLast()
→ "Cari yang terakhir"
23. Bagaimana dengan findIndex()?
Kamu sudah belajar:
let index = names.findIndex((name) => {
return name.length === 4;
});
Misalnya:
["John", "Mark", "Arun", "Steve"]
Hasil:
0
Karena John adalah element pertama yang memenuhi kondisi.
findIndex() mengembalikan:
index element pertama yang cocok.
24. findLastIndex()
Sekarang pasangan barunya:
findIndex()
↓
findLastIndex()
Misalnya:
let names = [
"John",
"Mark",
"Arun",
"David",
"Peter"
];
Kita cari nama dengan panjang 4:
let index = names.findLastIndex((name) => {
return name.length === 4;
});
Yang cocok:
index 0 → John ✅
index 1 → Mark ✅
index 2 → Arun ✅
index 3 → David ❌
index 4 → Peter ❌
Element terakhir yang cocok adalah:
Arun
Index-nya:
2
Jadi:
findLastIndex(...)
menghasilkan:
2
25. findLast() vs findLastIndex()
Ini sama seperti hubungan:
find()
findIndex()
Bedanya hanya:
findLast()
→ mendapatkan ELEMENT
findLastIndex()
→ mendapatkan INDEX
Contoh:
names.findLast(name => name.length === 4);
hasil:
"Arun"
Sedangkan:
names.findLastIndex(name => name.length === 4);
hasil:
2
26. Semua method pencarian sekarang lengkap
Kamu sekarang punya empat method:
ELEMENT INDEX
─────────── ───────────
dari depan find() findIndex()
dari belakang findLast() findLastIndex()
Ini adalah cheat sheet yang sangat bagus untuk dihafalkan.
27. Visual lengkap
Misalnya:
let names = [
"John",
"Mark",
"Arun",
"David",
"Peter"
];
Cari yang panjangnya 4.
DEPAN → → → → → BELAKANG
Index: 0 1 2 3 4
John Mark Arun David Peter
✅ ✅ ✅ ❌ ❌
find()
↓
John
findIndex()
↓
0
findLast()
↓
Arun
findLastIndex()
↓
2
28. Kenapa findLast() berguna?
Bayangkan data transaksi:
let transactions = [
{ id: 1, status: "success" },
{ id: 2, status: "failed" },
{ id: 3, status: "success" },
{ id: 4, status: "failed" }
];
Kita ingin:
Cari transaksi
successterakhir.
Tanpa findLast(), kamu mungkin perlu cara lain.
Dengan:
let lastSuccess = transactions.findLast((transaction) => {
return transaction.status === "success";
});
Hasil:
{ id: 3, status: "success" }
Ini sangat natural dibaca:
Find the last transaction whose status is success.
29. Contoh relevan dengan project movie
Misalnya:
let movies = [
{ name: "Movie A", rating: 3 },
{ name: "Movie B", rating: 5 },
{ name: "Movie C", rating: 4 },
{ name: "Movie D", rating: 5 }
];
Kita ingin:
Movie dengan rating 5 yang paling terakhir.
Gunakan:
let movie = movies.findLast((movie) => {
return movie.rating === 5;
});
Hasil:
{ name: "Movie D", rating: 5 }
Kalau menggunakan find():
let movie = movies.find((movie) => {
return movie.rating === 5;
});
Hasil:
{ name: "Movie B", rating: 5 }
Karena find() mengambil pertama.
30. findLastIndex() juga berguna untuk operasi Array
Misalnya:
let movies = [
{ name: "Movie A", rating: 3 },
{ name: "Movie B", rating: 5 },
{ name: "Movie C", rating: 4 },
{ name: "Movie D", rating: 5 }
];
Cari posisi movie rating 5 yang terakhir:
let index = movies.findLastIndex((movie) => {
return movie.rating === 5;
});
Hasil:
3
Kenapa?
0 → Movie A → 3 ❌
1 → Movie B → 5 ✅
2 → Movie C → 4 ❌
3 → Movie D → 5 ✅ ← terakhir
31. Hubungkan dengan findIndex() + splice()
Ini juga nyambung dengan lecture delete movie.
Sebelumnya:
let index = movies.findIndex((movie) => {
return movie.id === id;
});
movies.splice(index, 1);
Kalau suatu saat kamu ingin mencari kemunculan terakhir berdasarkan kondisi tertentu:
let index = movies.findLastIndex((movie) => {
return movie.rating === 5;
});
Kemudian bisa saja melakukan operasi berdasarkan index tersebut.
Jadi konsep dasarnya tetap sama:
findIndex()
→ cari posisi pertama
findLastIndex()
→ cari posisi terakhir
32. Kalau tidak menemukan element?
Sama seperti find():
find()
menghasilkan:
undefined
jika tidak ada yang cocok.
Begitu juga:
findLast()
menghasilkan:
undefined
Sedangkan:
findIndex()
menghasilkan:
-1
dan:
findLastIndex()
juga menghasilkan:
-1
Jadi:
find() → undefined jika tidak ketemu
findLast() → undefined jika tidak ketemu
findIndex() → -1 jika tidak ketemu
findLastIndex() → -1 jika tidak ketemu
33. Gabungkan semua materi lecture ini
Sekarang kita bisa membuat peta besar:
ARRAY METHODS
│
┌──────────────┴──────────────┐
│ │
MUTATING NON-MUTATING
│ │
↓ ↓
sort() toSorted()
reverse() toReversed()
splice() toSpliced()
Kemudian pencarian:
SEARCH
│
┌────────┴────────┐
│ │
DEPAN BELAKANG
│ │
↓ ↓
find() findLast()
findIndex() findLastIndex()
34. Cheat sheet besar
| Method | Fungsi | Original berubah? | Return |
|---|---|---|---|
sort() | Mengurutkan | ✅ | Array yang sama |
toSorted() | Membuat versi terurut | ❌ | Array baru |
reverse() | Membalik urutan | ✅ | Array yang sama |
toReversed() | Membuat versi terbalik | ❌ | Array baru |
splice() | Hapus/tambah/ganti | ✅ | Array element yang dihapus |
toSpliced() | Membuat versi hasil splice | ❌ | Array baru |
find() | Cari element pertama | ❌ | Element / undefined |
findLast() | Cari element terakhir | ❌ | Element / undefined |
findIndex() | Cari index pertama | ❌ | Number / -1 |
findLastIndex() | Cari index terakhir | ❌ | Number / -1 |
35. Bedakan slice() dan splice() dan toSpliced()
Ini wajib diperhatikan karena namanya mirip.
slice()
let result = arr.slice(1, 3);
Artinya:
Ambil sebagian Array untuk membuat Array baru.
original → TIDAK berubah
splice()
arr.splice(1, 2);
Artinya:
Hapus/tambah/ganti element pada Array asli.
original → BERUBAH
toSpliced()
let result = arr.toSpliced(1, 2);
Artinya:
Lakukan konsep splice, tetapi hasilnya diberikan sebagai Array baru.
original → TIDAK berubah
result → versi yang sudah di-splice
Jadi:
slice()
→ ambil sebagian
splice()
→ ubah original
toSpliced()
→ buat versi baru setelah operasi splice
36. Hubungan dengan prinsip yang sudah kamu pelajari
Sebelumnya kamu sudah belajar:
sort()
splice()
adalah mutating methods.
Sekarang JavaScript modern memberikan alternatif:
sort() → toSorted()
reverse() → toReversed()
splice() → toSpliced()
Ini sangat penting dalam konsep immutability.
Secara sederhana:
Jangan selalu mengubah data asli. Kadang lebih aman membuat versi baru.
Contohnya:
const original = [3, 1, 2];
const sorted = original.toSorted();
Sekarang kita punya:
original
↓
[3, 1, 2]
sorted
↓
[1, 2, 3]
Dua data berbeda.
37. Satu hal penting tentang const
Ini juga nyambung dengan materi const.
Misalnya:
const names = ["John", "Mark", "Arun"];
const tidak berarti Array tidak boleh berubah.
Dengan method mutating:
names.sort();
masih boleh.
Karena kita tidak mengganti binding names; kita mengubah isi Array.
Sedangkan:
names = ["A", "B"];
tidak boleh.
Dengan method non-destructive:
const sortedNames = names.toSorted();
kita membuat Array baru dan menyimpannya ke variable lain.
38. Mental model paling penting dari lecture ini
Kalau disederhanakan menjadi satu gambar:
ARRAY ASLI
│
┌───────────┴───────────┐
│ │
MUTATE COPY
│ │
↓ ↓
sort() toSorted()
reverse() toReversed()
splice() toSpliced()
│ │
↓ ↓
original berubah original tetap
+ Array baru
Dan untuk pencarian:
SEARCH
│
┌─────────┴─────────┐
↓ ↓
dari depan dari belakang
│ │
↓ ↓
find() findLast()
findIndex() findLastIndex()
│ │
↓ ↓
pertama cocok terakhir cocok
🧠 Kesimpulan yang wajib kamu ingat
ES2023
sort() // mutate
toSorted() // new Array
reverse() // mutate
toReversed() // new Array
splice() // mutate
toSpliced() // new Array
Pasangan ini harus kamu hafal.
ES2022
find()
findLast()
findIndex()
findLastIndex()
Cara mengingatnya:
find
→ dapat ELEMENT
findIndex
→ dapat INDEX
findLast
→ ELEMENT terakhir yang cocok
findLastIndex
→ INDEX terakhir yang cocok
Dan satu mental model terakhir:
sort → urutkan original
toSorted → buat versi terurut
reverse → balik original
toReversed → buat versi terbalik
splice → ubah original
toSpliced → buat versi hasil splice
find → cari pertama
findLast → cari terakhir
findIndex → posisi pertama
findLastIndex → posisi terakhir
Kalau kamu sudah memahami pola ini, sebenarnya lecture ini tidak terlalu banyak konsep baru. Yang paling penting adalah mengenali pasangan method dan memahami apakah method tersebut mengubah Array asli atau menghasilkan Array baru.