Chapter pengantar di Section Array dan Matriks telah memperkenalkan cell array sebagai wadah heterogen: kurung () mengambil sel, kurung kurawal {} mengambil isinya. Pengetahuan sebatas itu cepat menemui batasnya begitu kita mengolah data nyata — mengubah satu angka di dalam sel, menghapus sel tanpa merusak struktur, memproses seribu sel tanpa menulis loop, atau memilih antara cell array dan struct. Chapter ini memperdalam seluruhnya. Fokus bahasan kita:

  • Membuat cell array dengan tiga jalur, termasuk mengisi sel demi sel.
  • Indexing berantai, comma list, dan jebakan C(1){1}.
  • Perbedaan mengubah isi, mengganti sel, dan menghapus sel.
  • num2cell sebagai pelengkap mat2cell/cell2mat.
  • cellfun dengan anonymous function untuk memproses seluruh sel sekaligus.
  • Memutuskan kapan cell array lebih tepat daripada struct.

Membuat Cell Array: Tiga Jalur #

Aturan pembuatannya: kurung kurawal {} membuat sekaligus mengisi, fungsi cell() membuat kerangka kosong, dan pengisian per sel memakai C{indeks} = nilai. Mekanismenya: setiap sel adalah pointer independen, sehingga mengisi satu sel tidak menyentuh sel lain — MATLAB hanya menumbuhkan array bila indeks yang dituju belum ada.

matlab
C = {10, [20 30 40], 'lima'};

ruang = cell(1, 3);              % kerangka 1x3, semua sel kosong
ruang{2} = 'isi baru';
fprintf('ruang{2} = %s, numel sel 1 = %d\n', ruang{2}, numel(ruang{1}));

Output yang Dihasilkan:

text
ruang{2} = isi baru, numel sel 1 = 0

Mari kita bedah baris-baris kode di atas:

  1. Baris 1 (C = {10, ...}): tiga sel terisi sekaligus — skalar, vektor, dan teks hidup berdampingan tanpa konversi tipe.
  2. Baris 3 (cell(1, 3)): MATLAB mengalokasikan tiga sel kosong []; ukuran sudah final sehingga pengisian berikutnya tidak memicu realokasi memori berulang.
  3. Baris 4 (ruang{2} = ...): kurung kurawal mengarah ke isi sel ke-2 — hanya sel itu yang berubah; numel(ruang{1}) yang bernilai 0 membuktikan sel 1 tetap kosong.

Indexing Berantai dan Comma List #

Aturan lanjutan indexing: setelah sel dibuka dengan {}, hasilnya adalah array biasa yang bisa diiris lagi dengan (). Ekspresi C{2}(3) berarti “buka sel 2, ambil elemen ke-3”. Sebaliknya, urutan terbalik C(1){1} — kurung lalu kurung kurawal — tidak valid di MATLAB; simpan dulu hasil C(1) ke variabel bila kita butuh jalur tersebut.

matlab
fprintf('C{2}(3) = %d\n', C{2}(3));
fprintf('C{2}(1:2) = %d %d\n', C{2}(1:2));

[a, b] = C{1:2};                 % dua output = dua isi sel
gabung = [C{2}, C{2}];           % isi sel menyatu menjadi vektor
fprintf('a = %d, b(2) = %d\n', a, b(2));
fprintf('gabung = %d %d %d %d %d %d\n', gabung);

Output yang Dihasilkan:

text
C{2}(3) = 40
C{2}(1:2) = 20 30
a = 10, b(2) = 30
gabung = 20 30 40 20 30 40

Mari kita bedah baris-baris kode di atas:

  1. Baris 1-2 (C{2}(3), C{2}(1:2)): kurung kurawal membuka sel (matriks [20 30 40]), lalu kurung mengiris elemen atau rentangnya — pengindeksan berlapis dari luar ke dalam.
  2. Baris 4 ([a, b] = C{1:2}): ekspresi C{1:2} adalah comma list — deretan isi sel yang dipisah koma implisit, sehingga dua output menangkap dua isi sel.
  3. Baris 5 ([C{2}, C{2}]): isi sel keluar dari pembungkusnya lalu digabung dengan kurung siku — hasilnya vektor numerik 1×6, bukan cell array.

Mengubah Isi, Mengganti Sel, Menghapus Sel #

Tiga operasi berbeda sering tertukar, padahal mekanismenya bertolak belakang. Kurung kurawal menembus ke isi, kurung bekerja pada selnya, dan penghapusan memakai assignment array kosong pada sel:

OperasiKodeEfek
Ubah isi selC{2}(2) = 99elemen ke-2 di dalam sel berubah, sel tetap
Ganti selC(3) = {55}sel ke-3 kini membungkus nilai baru
Hapus selC(2) = []sel ke-3 hilang, cell menyusut
Kosongkan isiC{2} = []sel tetap ada, isinya []
matlab
C{2}(2) = 99;                    % ubah SATU ELEMEN di dalam sel
C(3) = {55};                     % ganti SEL ke-3 dengan sel pembungkus 55
C(2) = [];                       % hapus sel ke-2, cell menyusut
fprintf('C setelah C(2) dihapus : %dx%d, C{1} = %d, C{2} = %d\n', ...
        size(C, 1), size(C, 2), C{1}, C{2});

D = {1, 2, 3};
D{2} = [];                       % ISI sel dikosongkan, BUKAN sel dihapus
fprintf('D{2} = [] : size tetap %dx%d, numel(D{2}) = %d\n', ...
        size(D, 1), size(D, 2), numel(D{2}));

Output yang Dihasilkan:

text
C setelah C(2) dihapus : 1x2, C{1} = 10, C{2} = 55
D{2} = [] : size tetap 1x3, numel(D{2}) = 0

Mari kita bedah baris-baris kode di atas:

  1. Baris 1 (C{2}(2) = 99): matriks di dalam sel ke-2 berubah menjadi [20 99 40] — pengindeksan berantai juga bekerja untuk assignment.
  2. Baris 2 (C(3) = {55}): sisi kanan wajib cell array 1×1; menulis C(3) = 55 memicu galat karena kurung menuntut sesama cell.
  3. Baris 3 (C(2) = []): sel ke-2 lenyap, sel setelahnya bergeser — ukuran C menyusut dari 1×3 menjadi 1×2.
  4. Baris 7 (D{2} = []): kontras dengan baris 3 — isi sel menjadi array kosong [] (terbukti dari numel 0) namun posisi sel ke-2 tetap ditempati.

num2cell, mat2cell, cell2mat #

Fungsi jembatan matriks ⇄ cell array kini lengkap: mat2cell memecah matriks menjadi blok, cell2mat merakit balik, dan num2cell membungkus setiap elemen array menjadi sel sendirian — pintu masuk paling sering dipakai sebelum cellfun.

matlab
v = [5 10 15 20];
selV = num2cell(v);
fprintf('num2cell : class %s, selV{3} = %d\n', class(selV), selV{3});

M = [1 2 3; 4 5 6];
blok = mat2cell(M, [1 1], [2 1]);
gab = cell2mat(blok);
fprintf('cell2mat : gab(2,3) = %d\n', gab(2, 3));

Output yang Dihasilkan:

text
num2cell : class cell, selV{3} = 15
cell2mat : gab(2,3) = 6

Mari kita bedah baris-baris kode di atas:

  1. Baris 2 (num2cell(v)): vektor 1×4 menjadi cell 1×4 — tiap sel berisi satu skalar; selV{3} bernilai 15.
  2. Baris 6 (mat2cell(M, [1 1], [2 1])): baris terbagi 1+1, kolom terbagi 2+1 — empat blok dalam cell 2×2.
  3. Baris 7 (cell2mat(blok)): blok-blok disusun kembali; gab(2,3) = elemen baris-2 kolom-3 dari M, yaitu 6.

cellfun: Memproses Semua Sel Sekaligus #

Aturannya: cellfun(fungsi, C) menjalankan satu fungsi pada setiap sel tanpa loop. Fungsi tersebut bisa function handle biasa (@sqrt) maupun anonymous function (@(x) ...) yang kita definisikan sebaris — teknik dari Chapter Anonymous Functions. Mekanismenya: cellfun membuka tiap sel, memanggil fungsinya, lalu mengumpulkan hasil; bila semua hasil berupa skalar sejenis, MATLAB menggabungkannya menjadi array biasa, dan bila tidak, opsi 'UniformOutput', false membuat hasil tetap berupa cell array.

matlab
data = {1, 4, 9, 16};
akar = cellfun(@sqrt, data);     % semua hasil skalar → array biasa
label = cellfun(@(x) sprintf('nilai %d', x), data, 'UniformOutput', false);
fprintf('akar    : %.4f %.4f %.4f %.4f\n', akar);
fprintf('label{2}: %s\n', label{2});

Output yang Dihasilkan:

text
akar    : 1.0000 2.0000 3.0000 4.0000
label{2}: nilai 4

Mari kita bedah baris-baris kode di atas:

  1. Baris 2 (cellfun(@sqrt, data)): sqrt dijalankan pada isi tiap sel; empat skalar dikembalikan sebagai double 1×4 — tanpa 'UniformOutput' karena hasil memang seragam.
  2. Baris 3 (cellfun(@(x) sprintf(...), ...)): anonymous function menghasilkan char per sel; 'UniformOutput', false wajib agar hasil berupa cell 1×4 yang menampung teks.
  3. cellfun galat bila isi sel bukan sesuatu yang bisa diproses fungsinya — @sqrt pada sel berisi char menghentikan eksekusi dengan pesan galat.

Menyimpan Campuran dan Memilih Struct #

Satu cell array sanggup menampung matriks, teks, sekaligus struct — dan cellfun(@numel, ...) tetap bekerja karena numel menerima semua kelas:

matlab
mhs = struct('nama', 'Budi', 'umur', 21);
arsip = {[90 85; 78 88], 'laporan akhir', mhs};
fprintf('arsip{1}(1,2) = %d\n', arsip{1}(1, 2));
fprintf('arsip{3}.nama = %s, umur %d\n', arsip{3}.nama, arsip{3}.umur);
jumlahElemen = cellfun(@numel, arsip, 'UniformOutput', false);
fprintf('numel tiap sel: %d %d %d\n', jumlahElemen{:});

Output yang Dihasilkan:

text
arsip{1}(1,2) = 85
arsip{3}.nama = Budi, umur 21
numel tiap sel: 4 13 1

Kapan cell array, kapan struct? Kuncinya pada makna posisi versus makna nama:

KriteriaCell arrayStructure array
Akses dataposisi/indeks: C{2}nama field: S.nama
Cocok untukkumpulan sejenis (daftar berkas, blok matriks)record dengan field tetap
Iterasi seluruh isicellfun naturalloop + fieldnames
Field berubah-ubahtak relevan (tak ada nama)dynamic field S.(var)
Data numerik massalboros — tiap sel ber-pointerboros — akses per record

Ringkasan #

Pembuatan cell array memakai {} sekaligus-isi, cell() untuk kerangka, atau C{indeks} = nilai per sel. Indexing berantai C{2}(3) membuka sel lalu mengiris isinya, comma list C{:} menjatuhkan seluruh isi sekaligus, dan C(1){1} tidak valid di MATLAB. Empat operasi modifikasi — mengubah isi C{2}(2) = 99, mengganti sel C(3) = {55}, menghapus sel C(2) = [], mengosongkan isi C{2} = [] — masing-masing meninggalkan jejak struktur berbeda. Fungsi num2cell/mat2cell/cell2mat menjembatani matriks dan cell, cellfun dengan anonymous function menggantikan loop, dan pilihan cell array vs struct ditentukan oleh akses posisi vs akses nama. Berkas contoh.m menguji seluruh contoh chapter ini secara utuh.