kodingup.camp

Beranda/JavaScript Mastery: Object & Data

Mengolah Data Teks

Modul 9 dari 144 menit bacaTextual Data Handling

Isi modul

    Kenapa ini penting

    Teks ada di mana-mana: nama pengguna, alamat email, nomor telepon, judul artikel, kata kunci pencarian, isi pesan chat. Hampir setiap fitur aplikasi butuh mengolah string: membersihkan spasi dari input form, mengecek apakah email mengandung @, memotong deskripsi panjang menjadi ringkasan, membuat slug URL dari judul artikel, menyamarkan nomor kartu, atau menyusun pesan notifikasi.

    Kabar baiknya, JavaScript menyediakan banyak method string bawaan yang siap pakai. Kamu tidak perlu menulis loop karakter satu per satu untuk tugas umum. Ingat dari modul 7: string itu immutable, jadi semua method di modul ini mengembalikan string baru dan tidak mengubah string aslinya. Simpan hasilnya kalau ingin dipakai.

    Konsep inti

    Indeks dan panjang

    String adalah deretan karakter yang diberi nomor mulai dari 0. str.length memberi jumlah karakter. str[0] atau str.at(0) mengambil karakter pertama. str.at(-1) mengambil karakter terakhir (indeks negatif dihitung dari belakang), yang lebih ringkas daripada str[str.length - 1].

    Catatan lanjutan: length menghitung code unit UTF-16, bukan karakter yang terlihat. Emoji seperti "😀" punya length 2. Untuk menghitung karakter yang terlihat secara lebih akurat, pakai [...str].length atau Array.from(str).length.

    Mengambil bagian string: slice

    str.slice(awal, akhir) mengambil potongan dari indeks awal sampai sebelum akhir. Kalau akhir tidak diisi, diambil sampai ujung. Indeks negatif dihitung dari belakang: str.slice(-3) mengambil tiga karakter terakhir. Ada juga substring yang mirip tapi tidak mendukung indeks negatif; untuk kode baru, slice lebih konsisten.

    Mencari dalam string

    Method Hasil Contoh
    includes(x) true/false "halo dunia".includes("dunia") → true
    startsWith(x) true/false "08123".startsWith("08") → true
    endsWith(x) true/false "foto.png".endsWith(".png") → true
    indexOf(x) posisi pertama atau -1 "banana".indexOf("n") → 2
    lastIndexOf(x) posisi terakhir atau -1 "banana".lastIndexOf("n") → 4

    Semua pencarian ini case-sensitive (membedakan huruf besar dan kecil). Untuk pencarian yang tidak peduli besar-kecil, ubah kedua sisi ke toLowerCase() dulu.

    Memecah dan menggabungkan

    str.split(pemisah) memecah string menjadi array. arr.join(pemisah) menggabungkan array menjadi string. Pasangan ini sangat sering dipakai: misalnya "a,b,c".split(",") menghasilkan ["a", "b", "c"]. split("") memecah per karakter (hati-hati dengan emoji, lebih aman pakai [...str]).

    Mengganti teks

    str.replace(cari, ganti) hanya mengganti kemunculan pertama jika cari berupa string. str.replaceAll(cari, ganti) mengganti semua kemunculan. Keduanya juga menerima regular expression (pola pencarian); replaceAll dengan regex wajib memakai flag g.

    Merapikan: trim, pad, repeat, case

    Template literal

    Template literal ditulis dengan backtick dan mendukung:

    Analogi: template literal seperti formulir isian dengan kotak kosong; kamu tinggal menaruh data di kotak ${} dan formulir rapi tercetak.

    Membandingkan teks

    Untuk mengurutkan teks sesuai aturan bahasa, pakai a.localeCompare(b, "id"). Hasilnya negatif jika a di depan b, positif jika di belakang, dan 0 jika sama. Ini akan dipakai lagi di modul 11 saat mengurutkan array.

    Contoh kode

    // 1) Indeks, panjang, at
    const kota = "Yogyakarta";
    console.log(kota.length, kota[0], kota.at(-1)); // → 10 Y a
    console.log("😀".length, [..."😀"].length);     // → 2 1
    
    // 2) slice
    const judul = "Belajar JavaScript dari Nol";
    console.log(judul.slice(0, 7)); // → Belajar
    console.log(judul.slice(8));    // → JavaScript dari Nol
    console.log(judul.slice(-3));   // → Nol
    
    // Potong deskripsi panjang dengan elipsis
    function ringkas(teks, maks) {
      return teks.length > maks ? teks.slice(0, maks).trimEnd() + "..." : teks;
    }
    console.log(ringkas("Sepatu lari ringan untuk latihan harian", 18)); // → Sepatu lari ringan...
    
    // 3) Mencari
    const email = "  Rina.Putri@Gmail.com ";
    const emailBersih = email.trim().toLowerCase();
    console.log(emailBersih);                        // → rina.putri@gmail.com
    console.log(emailBersih.includes("@"));          // → true
    console.log(emailBersih.endsWith("@gmail.com")); // → true
    console.log(emailBersih.indexOf("@"));           // → 10
    console.log("Halo".includes("halo"));            // → false (case-sensitive)
    
    // 4) split dan join
    const tagTeks = "javascript, web,  pemula ,frontend";
    const tags = tagTeks.split(",").map((t) => t.trim());
    console.log(tags);             // → [ 'javascript', 'web', 'pemula', 'frontend' ]
    console.log(tags.join(" | ")); // → javascript | web | pemula | frontend
    
    // 5) replace vs replaceAll
    const tanggal = "2026-10-23";
    console.log(tanggal.replace("-", "/"));    // → 2026/10-23 (hanya yang pertama)
    console.log(tanggal.replaceAll("-", "/")); // → 2026/10/23
    
    // Membuat slug URL dari judul
    function buatSlug(teks) {
      return teks
        .trim()
        .toLowerCase()
        .replaceAll(/[^a-z0-9\s-]/g, "") // buang karakter selain huruf, angka, spasi, strip
        .replaceAll(/\s+/g, "-");        // spasi (satu atau lebih) jadi strip
    }
    console.log(buatSlug("  Tips Hemat: Belanja Bulanan 2026!  ")); // → tips-hemat-belanja-bulanan-2026
    
    // 6) padStart, padEnd, repeat
    console.log(String(7).padStart(3, "0")); // → 007
    const kartu = "4111222233334444";
    console.log(kartu.slice(-4).padStart(kartu.length, "*")); // → ************4444
    console.log("Nama".padEnd(10, ".") + "Rina"); // → Nama......Rina
    console.log("=".repeat(20));                  // → ====================
    
    // Kapitalisasi tiap kata
    const kapital = (teks) =>
      teks
        .toLowerCase()
        .split(" ")
        .map((kata) => kata.charAt(0).toUpperCase() + kata.slice(1))
        .join(" ");
    console.log(kapital("bUDI santoso wIJAYA")); // → Budi Santoso Wijaya
    
    // 7) Template literal
    const pelanggan = { nama: "Sari", poin: 1250 };
    const pesan = `Halo ${pelanggan.nama}!
    Poin kamu: ${pelanggan.poin.toLocaleString("id-ID")}
    Status: ${pelanggan.poin >= 1000 ? "Gold" : "Silver"}`;
    console.log(pesan);
    // → Halo Sari!
    // → Poin kamu: 1.250
    // → Status: Gold
    
    // Tagged template sederhana: menebalkan nilai yang disisipkan
    function tebal(bagian, ...nilai) {
      return bagian.reduce((hasil, teks, i) => hasil + teks + (i < nilai.length ? `**${nilai[i]}**` : ""), "");
    }
    console.log(tebal`Pesanan ${"A12"} berisi ${3} item`); // → Pesanan **A12** berisi **3** item
    
    // 8) Membandingkan teks sesuai bahasa
    console.log("apel".localeCompare("Belimbing", "id") < 0); // → true (apel di depan)
    

    Kesalahan umum

    1. Memanggil method tanpa menyimpan hasilnya. input.trim() saja tidak mengubah input. Simpan: const bersih = input.trim().
    2. Memakai replace padahal ingin mengganti semua. replace dengan string hanya mengganti yang pertama. Pakai replaceAll.
    3. Lupa bahwa pencarian case-sensitive. "Halo".includes("halo") bernilai false. Samakan dulu dengan toLowerCase().
    4. Salah paham argumen kedua slice. slice(2, 5) mengambil indeks 2, 3, 4 (bukan sampai 5). Argumen kedua adalah posisi berhenti, bukan jumlah karakter.
    5. Membalik atau memotong string berisi emoji dengan split(""). Emoji bisa pecah menjadi karakter rusak. Pakai [...str] untuk memecah per karakter.

    Latihan

    1. Mudah, Buat function inisial(nama) yang mengubah "budi santoso" menjadi "BS".
    2. Sedang, Buat function samarkanEmail(email) yang mengubah "rinaputri@gmail.com" menjadi "ri*******@gmail.com" (dua huruf pertama terlihat, sisanya bintang sampai sebelum @).
    3. Menantang, Buat function hitungKata(teks) yang mengembalikan object berisi jumlah kemunculan setiap kata (tidak peduli huruf besar/kecil, abaikan tanda baca .,!?). Contoh: "Kopi enak. Kopi murah!" menghasilkan { kopi: 2, enak: 1, murah: 1 }.
    Lihat solusi
    // 1) Mudah
    function inisial(nama) {
      return nama
        .trim()
        .split(" ")
        .map((kata) => kata[0].toUpperCase())
        .join("");
    }
    console.log(inisial("budi santoso")); // → BS
    
    // 2) Sedang
    function samarkanEmail(email) {
      const posisiAt = email.indexOf("@");
      const nama = email.slice(0, posisiAt);
      const domain = email.slice(posisiAt);
      return nama.slice(0, 2).padEnd(nama.length, "*") + domain;
    }
    console.log(samarkanEmail("rinaputri@gmail.com")); // → ri*******@gmail.com
    
    // 3) Menantang
    function hitungKata(teks) {
      const hasil = {};
      const kataKata = teks.toLowerCase().replaceAll(/[.,!?]/g, "").split(/\s+/).filter(Boolean);
      for (const kata of kataKata) {
        hasil[kata] = (hasil[kata] ?? 0) + 1;
      }
      return hasil;
    }
    console.log(hitungKata("Kopi enak. Kopi murah!")); // → { kopi: 2, enak: 1, murah: 1 }
    

    Ringkasan

    Kuis pemahaman

    Pilih satu jawaban per soal. Penjelasan muncul setelah kamu menjawab.