`Array` na bagay

`Array` na bagay

Ipinaliliwanag ng artikulong ito ang tungkol sa Array na bagay.

Ipapaliwanag ko ang mga praktikal na gamit ng array nang sunud-sunod at madaling maintindihan.

YouTube Video

Array na bagay

Ang Array na bagay ng JavaScript ay isa sa pinakamahalagang istruktura na bumubuo ng pundasyon ng iba't ibang uri ng pagpoproseso ng datos. Mula sa mga pangunahing operasyon ng array hanggang sa mga mas mataas na antas ng mga function na kapaki-pakinabang para sa episyenteng transformasyon ng data, maraming mga katangian ang dapat mong malaman.

Pangunahing Kaalaman sa Array

Sa JavaScript, ang mga array ay pangunahing estruktura ng datos para sa paghawak ng maraming halaga nang sabay-sabay. Dito, ipakikilala namin kung paano gumawa ng array at kung paano basahin at isulat ang kanilang mga elemento gamit ang mga simpleng halimbawa.

 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
  • Ipinapakita ng code na ito ang tatlong paraan para gumawa ng array, kung paano basahin at i-update ang mga elemento gamit ang mga index, at kung paano makuha ang haba gamit ang property na length.
  • Ang mga array literal ang pinakakaraniwan at madaling basahin, at madalas ginagamit sa pang-araw-araw na sitwasyon.

Pagdaragdag at Pag-aalis ng mga Elemento (sa Dulo o Simula)

Pinapadali ng mga array ang pagdaragdag o pag-aalis ng mga elemento sa dulo o simula. Kapaki-pakinabang din ang mga operasyong ito kapag gumagawa ng mga istrukturang tulad ng stack o 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' ]
  • Ang push at pop ay gumagana sa dulo ng array. Ang mga ito ay ideal para sa paggawa ng stack na istruktura.
  • Ang unshift at shift ay gumagana sa simula ng array. Gayunpaman, tandaan na ang pag-operate sa simula ay nangangailangan ng paglipat ng lahat ng index ng elemento sa loob, kaya't mas mabagal ito.

Paghawak ng mga Elemento sa Gitna (splice at slice)

Kapag humahawak ng mga elemento sa gitna ng array, dapat kang pumili sa pagitan ng splice at slice depende kung gusto mong baguhin ang orihinal na array o hindi. Kung gusto mo lang kumuha ng bahagi ng isang array, gamitin ang slice; kung gusto mong baguhin mismo ang array, tulad ng pag-insert o pagtanggal ng mga elemento, gamitin ang 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 ]
  • Ang slice ay kumukuha lamang ng mga elemento at hindi binabago ang orihinal na array.
  • Ang splice ay nagdadagdag o nag-aalis ng mga elemento at binabago mismo ang array, kaya't mag-ingat sa epekto nito sa pag-uugali ng programa.

Pag-uulit (for / for...of / forEach)

May ilang paraan para maproseso ang mga array nang sunud-sunod, at maaari kang pumili batay sa layunin at iyong paboritong coding style. Narito ang tatlong karaniwang paraan ng pag-loop.

 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});
  • Ang for loop ay pinaka-flexible, hinahayaan kang gamitin ang mga index at magbigay ng mas detalyadong kontrol sa pag-uulit gamit ang break at iba pang statements.
  • Nagbibigay ang for...of ng maigsi at madaling maintindihang paraan para hawakan ang mga halaga ng elemento at ito ang pinaka-balanseng paraan pagdating sa readability.
  • Ang forEach ay nagpapahintulot ng functional-style na code at mabuti para sa side-effect na mga operasyon tulad ng pag-log o pag-update ng datos sa bawat elemento. Ngunit tandaan: hindi mo magagamit ang break o continue, at ito ay hindi angkop sa asynchronous processing gamit ang await.

map / filter / reduce — Mas Mataas na Uri ng mga Function

map, filter, at reduce ay mga higher-order function na madalas gamitin kapag nagta-transform, nagfi-filter, o nag-a-aggregate ng mga array. Dahil malinaw mong naipapahayag ang paulit-ulit na proseso, nagiging simple at madaling maintindihan ang iyong code.

 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
  • Pinapayagan ka ng mga method na ito na mag-focus sa nais mong gawin sa isang deklaratibong estilo, na nagpapahusay ng readability at nakatutulong umiwas sa hindi inaasahang epekto.

find / findIndex / some / every

Narito ang buod ng mga search at condition-checking na mga method. Kapaki-pakinabang ang mga ito upang makahanap ng mga elementong tumutugma sa partikular na kondisyon o magsagawa ng boolean na tsek sa set.

 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
  • Ang find ay ibinabalik ang unang elementong tumutugma sa kondisyon.
  • Ang findIndex ay ibinabalik ang index ng elementong tumutugma sa kondisyon.
  • Ang some ay ibinabalik ang true kung may kahit isang elementong tumutugon sa kondisyon.
  • Ang every ay ibinabalik ang true kung lahat ng elemento ay tumutugon sa kondisyon.

Lahat ng ito ay napaka-kapaki-pakinabang sa pagpoproseso ng array, kaya't ang tamang paggamit ng mga ito ayon sa sitwasyon ay magpapaikli at magpapalinaw ng iyong code.

Pag-aayos at Paghahambing na mga Function

Inaayos ang array gamit ang sort, ngunit bilang default ay kinukumpara nito ang mga elemento bilang string, kaya maaaring magdulot ito ng hindi inaasahang resulta kapag nag-aayos ng mga numero.

 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 } ]
  • Kapag nagaayos ng mga numero o objects, palaging magbigay ng function sa paghahambing upang maayos ang pagkakasunod-sunod ayon sa iyong layunin.
  • Sa function sa paghahambing, ang negatibo na resulta ay inilalagay si a bago si b, ang positibo ay inilalagay si b bago si a, at ang 0 ay hindi binabago ang kanilang ayos.

Pagkopya ng Array at Immutability

Kapag nagko-copy ng mga array, mahalagang maintindihan ang pagkakaiba ng 'reference copy' at 'shallow copy.'. Lalo na, dapat alm niyo na kung may mga object sa loob ng array, ang shallow copy ay magreresulta sa pag-share ng mga internal na object.

Reference copy

Kapag nag-assign ka ng array sa ibang variable, hindi nadoduplicate ang mismong array; sa halip, ang 'reference' na tumuturo sa parehong array ang kinokopya.

 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 ]
  • Sa reference copy, kapag binago mo ang laman ng array gamit ang nakopyang variable, magrereflect din ang mga pagbabagong iyon sa orihinal na variable na tumutukoy sa parehong array.

Shallow copy

Ang paggamit ng slice() o spread syntax ay gumagawa ng 'shallow copy' dahil ang mga value lang ang nadoduplicate; hiwalay na entity ang orihinal at naka-copy na array.

 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 ]
  • Ipinapakita ng code na ito na ang shallow copy ng isang array na ginawa gamit ang slice() o spread syntax ay hindi nakakaapekto sa orihinal na array.

Shallow copy at pagiging immutable

Kahit kinopya mo ang array gamit ang 'shallow copy', posibleng mangyari ang hindi inaasahang sharing kapag may mga object sa loob ng array.

 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 } ]
  • Ipinapakita ng code na ito na sa shallow copy, shared ang mga object sa loob, kaya kapag binago ang mga inner object, maaapektuhan ang orihinal at ang copy na array.
  • Kung kailangan mo ng independiyenteng datos, kailangan mong gumamit ng 'deep copy' tulad ng structuredClone() o JSON conversion.

Mga kapaki-pakinabang na utility method

Ang mga sumusunod ay mga utility method na madalas gamitin kapag nagtatrabaho sa mga array. Kung gagamitin mo ang mga ito nang wasto ayon sa iyong layunin, makakagawa ka ng maikli at madaling basahing code.

includes

Ang includes method ay tinitingnan kung ang isang partikular na value ay kasama sa 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
  • Sa code na ito, ginamit ang includes method para madaling malaman kung mayroong tinukoy na value sa loob ng array.

concat

Ang concat method ay nagbabalik ng bagong array na nagdadagdag ng tinukoy na array o value sa dulo, at hindi binabago ang orihinal na array.

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 ]
  • Ipinapakita ng code na ito na hindi destructive ang concat, kaya makakagawa ka ng bagong array nang hindi binabago ang orihinal.

flat

Sa paggamit ng flat method, puwede mong gawing isang layer ang mga nested na array.

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 ] ]
  • Ipinapakita ng code na ito ang resulta ng pag-flatten ng array ng isang level.
  • Dahil puwedeng tukuyin ang lalim sa flat, flexible mong magagawang iayos ang nesting base sa pangangailangan.

flatMap

Ang flatMap method ay nag-a-apply ng transformation sa bawat element at awtomatikong pinapaplat ang resulta sa isang dimensional na array.

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' ]
  • Ipinapakita ng code na ito ang halimbawa kung saan bawat string sa array ay hinahati ayon sa space, tapos pinagsasama at pinapaplat sa isang array.

join

Ang join method ay gumagawa ng string sa pamamagitan ng pagsasama-sama ng mga element ng array gamit ang itinakdang separator.

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
  • Sa code na ito, ginamit ang join method para gawing isang string na may comma bilang separator ang isang array.

Karaniwang Pagkakamali

Sa unang tingin ay mukhang simple ang operasyon sa array, pero marami itong aspeto na madaling magdulot ng hindi sinasadyang pagkilos. Maraming madalas hindi mapansin na pagkakamali sa pang-araw-araw na paggamit ng array, kaya kung iisaisip mo ang mga sumusunod na punto ay mapapabuti ang reliability ng iyong code.

  • Ang sort() ng Array ay nag-aayos gamit ang paghahambing ng string bilang default. Para tama ang pag-aayos ng mga numero, dapat palaging magbigay ng function na paghahambing.
  • Ang pagkopya ng array (gamit ang slice o spread syntax, atbp.) ay laging gumagawa ng shallow copy. Kung may mga object sa iyong array, mag-ingat dahil maaaring hindi sinasadyang mabago ang orihinal na data.
  • Ang splice ay isang destructive na method na direktang nagbabago ng array, habang ang slice ay isang non-destructive na method na hindi nagbabago ng orihinal na array. Mahalagang gamitin ang mga ito nang tama ayon sa iyong pangangailangan.
  • Ang forEach ay hindi angkop para sa mga loop na may asynchronous na proseso gamit ang await. Kung gusto mong tiyak na maisagawa ang asynchronous processing nang sunud-sunod, inirerekomenda ang paggamit ng for...of.

Praktikal na Halimbawa

Narito ang isang halimbawa ng pagsasama ng mga array method upang 'kunin ang kabuuang edad mula sa user data, piliin ang mga 30 pataas, at gumawa ng listahan ng mga pangalan.'.

 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' ]
  • Sa pamamagitan ng pagcha-chain ng reduce, filter, at map, madaling maisusulat ang aggregation, condition extraction, at transformation ng data.
  • Ang ganitong 'data processing pipeline' ay madaling basahin, kaunting side effects, kaya't madalas gamitin sa totoong mga aplikasyon.

Buod

Sa mga array ng JavaScript, kahit ang mga simpleng operasyon ay malawak ang aplikasyon, at gamit ang high-order function ay nagiging mas maigsi at mas malinaw ang iyong code. Maraming dapat maintindihan, ngunit kapag na-master mo ang tamang paggamit ng bawat isa, magiging mas madali at mabilis ang pagpoproseso ng datos.

Maaari mong sundan ang artikulo sa itaas gamit ang Visual Studio Code sa aming YouTube channel. Paki-check din ang aming YouTube channel.

YouTube Video