Kunci jawaban 04 Latihan Struktur Data.
4.1 Jumlah dari Rentang
function range(start, end, step = start < end ? 1 : -1) {
let hasil = [];
if (step > 0) {
for (let i = start; i <= end; i += step) hasil.push(i);
} else {
for (let i = start; i >= end; i += step) hasil.push(i);
}
return hasil;
}
function sum(array) {
let total = 0;
for (let nilai of array) total += nilai;
return total;
}Kenapa: default step pakai ternary yang membaca start dan end, jadi arahnya otomatis benar (range(5, 2) tanpa step tetap turun). Karena arah loop naik dan turun butuh perbandingan berbeda (<= vs >=), dipisah dua cabang. sum cukup for/of karena cuma butuh nilainya.
→ Soal: 04 Latihan Struktur Data > 4.1 Jumlah dari Rentang
4.2 Membalik Array
function reverseArray(array) {
let hasil = [];
for (let i = array.length - 1; i >= 0; i--) {
hasil.push(array[i]);
}
return hasil;
}
function reverseArrayInPlace(array) {
for (let i = 0; i < Math.floor(array.length / 2); i++) {
let j = array.length - 1 - i;
let tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
return array;
}Kenapa: reverseArray (murni) aman karena bikin array baru — berguna di lebih banyak situasi. reverseArrayInPlace lebih cepat dan hemat memori: ia menukar pasangan cermin (elemen i dengan array.length - 1 - i) sampai setengah panjang; elemen tengah (kalau ganjil) tak perlu disentuh. Variabel tmp menahan satu nilai supaya gak ketimpa saat menukar.
→ Soal: 04 Latihan Struktur Data > 4.2 Membalik Array
4.3 List Bertaut
function arrayToList(array) {
let list = null;
for (let i = array.length - 1; i >= 0; i--) {
list = {value: array[i], rest: list};
}
return list;
}
function listToArray(list) {
let array = [];
for (let node = list; node; node = node.rest) {
array.push(node.value);
}
return array;
}
function prepend(value, list) {
return {value, rest: list};
}
function nth(list, n) {
if (!list) return undefined;
else if (n == 0) return list.value;
else return nth(list.rest, n - 1);
}Kenapa: arrayToList membangun dari belakang, jadi tiap sel baru menunjuk sel yang udah dibuat. Pola for (let node = list; node; node = node.rest) “berjalan” dari kepala ke ekor sampai node jadi null. nth rekursif: cek !list dulu supaya gak error saat membaca .value dari null; tiap langkah mengecilkan n dan turun ke rest.
→ Soal: 04 Latihan Struktur Data > 4.3 List Bertaut
4.4 Perbandingan Dalam
function deepEqual(a, b) {
if (a === b) return true;
if (a == null || typeof a != "object" ||
b == null || typeof b != "object") {
return false;
}
let kunciA = Object.keys(a);
let kunciB = Object.keys(b);
if (kunciA.length != kunciB.length) return false;
for (let kunci of kunciA) {
if (!kunciB.includes(kunci)) return false;
if (!deepEqual(a[kunci], b[kunci])) return false;
}
return true;
}Kenapa: urutan cek penting. a === b menangani nilai primitif sama dan objek yang identitasnya sama. Baris kedua menangani semua kasus di mana minimal satu bukan objek (termasuk null, yang typeof-nya menipu jadi "object") — kalau sampai sini, pasti gak sama. Sisanya baru perbandingan properti: jumlah kunci harus sama, dan tiap nilai dibandingkan rekursif, jadi objek bersarang seperti {is: "an"} ikut dicek isinya.