מערכים

מערך הוא רשימה מסודרת של ערכים. אחד ממבני הנתונים החשובים ביותר ב-JavaScript.


יצירת מערך

// שיטה 1: סוגריים מרובעות (נפוץ)
let fruits = ["תפוח", "בננה", "תפוז"];

// שיטה 2: constructor (פחות נפוץ)
let numbers = new Array(1, 2, 3);

// מערך ריק
let empty = [];

// מערך עם סוגים מעורבים
let mixed = [1, "שלום", true, null, { name: "דן" }];

גישה לאיברים

מערכים מתחילים מאינדקס 0:

let fruits = ["תפוח", "בננה", "תפוז"];

console.log(fruits[0]);  // "תפוח"
console.log(fruits[1]);  // "בננה"
console.log(fruits[2]);  // "תפוז"
console.log(fruits[3]);  // undefined (לא קיים)

// האיבר האחרון
console.log(fruits[fruits.length - 1]);  // "תפוז"

// שינוי ערך
fruits[1] = "מנגו";
console.log(fruits);  // ["תפוח", "מנגו", "תפוז"]

אורך המערך (length)

let fruits = ["תפוח", "בננה", "תפוז"];

console.log(fruits.length);  // 3

// שימוש בלולאה
for (let i = 0; i < fruits.length; i++) {
    console.log(fruits[i]);
}

הוספה והסרה של איברים

push - הוספה לסוף

let fruits = ["תפוח", "בננה"];
fruits.push("תפוז");
console.log(fruits);  // ["תפוח", "בננה", "תפוז"]

// אפשר להוסיף כמה בבת אחת
fruits.push("מנגו", "ענבים");

pop - הסרה מהסוף

let fruits = ["תפוח", "בננה", "תפוז"];
let removed = fruits.pop();
console.log(removed);  // "תפוז"
console.log(fruits);   // ["תפוח", "בננה"]

unshift - הוספה להתחלה

let fruits = ["בננה", "תפוז"];
fruits.unshift("תפוח");
console.log(fruits);  // ["תפוח", "בננה", "תפוז"]

shift - הסרה מההתחלה

let fruits = ["תפוח", "בננה", "תפוז"];
let removed = fruits.shift();
console.log(removed);  // "תפוח"
console.log(fruits);   // ["בננה", "תפוז"]

splice - הוספה/הסרה ממיקום ספציפי

// התחביר: array.splice(start, deleteCount, items...)

let fruits = ["תפוח", "בננה", "תפוז", "מנגו"];

// הסרת 2 איברים מאינדקס 1
let removed = fruits.splice(1, 2);
console.log(removed);  // ["בננה", "תפוז"]
console.log(fruits);   // ["תפוח", "מנגו"]

// הוספה מבלי להסיר
fruits.splice(1, 0, "אבטיח");
console.log(fruits);  // ["תפוח", "אבטיח", "מנגו"]

// החלפה
fruits.splice(1, 1, "ענבים", "אננס");
console.log(fruits);  // ["תפוח", "ענבים", "אננס", "מנגו"]

slice - חיתוך (ללא שינוי המקור)

let fruits = ["תפוח", "בננה", "תפוז", "מנגו", "ענבים"];

// מאינדקס 1 עד 3 (לא כולל)
let sliced = fruits.slice(1, 3);
console.log(sliced);  // ["בננה", "תפוז"]
console.log(fruits);  // לא השתנה!

// מאינדקס 2 עד הסוף
console.log(fruits.slice(2));  // ["תפוז", "מנגו", "ענבים"]

// שלילי - מהסוף
console.log(fruits.slice(-2));  // ["מנגו", "ענבים"]

// העתקת מערך
let copy = fruits.slice();

חיפוש במערך

indexOf - מיקום ראשון

let fruits = ["תפוח", "בננה", "תפוז", "בננה"];

console.log(fruits.indexOf("בננה"));   // 1
console.log(fruits.indexOf("מנגו"));   // -1 (לא נמצא)

lastIndexOf - מיקום אחרון

let fruits = ["תפוח", "בננה", "תפוז", "בננה"];
console.log(fruits.lastIndexOf("בננה"));  // 3

includes - האם קיים

let fruits = ["תפוח", "בננה", "תפוז"];

console.log(fruits.includes("בננה"));  // true
console.log(fruits.includes("מנגו"));  // false

find - מציאת איבר לפי תנאי

let numbers = [5, 12, 8, 130, 44];

let found = numbers.find(num => num > 10);
console.log(found);  // 12 (הראשון שעונה על התנאי)

// עם אובייקטים
let users = [
    { id: 1, name: "דן" },
    { id: 2, name: "דנה" }
];
let user = users.find(u => u.id === 2);
console.log(user);  // { id: 2, name: "דנה" }

findIndex - אינדקס לפי תנאי

let numbers = [5, 12, 8, 130, 44];
let index = numbers.findIndex(num => num > 10);
console.log(index);  // 1

מתודות לולאה

forEach - מעבר על כל איבר

let fruits = ["תפוח", "בננה", "תפוז"];

fruits.forEach((fruit, index) => {
    console.log(`${index}: ${fruit}`);
});
// 0: תפוח
// 1: בננה
// 2: תפוז

map - יצירת מערך חדש מהמרה

let numbers = [1, 2, 3, 4, 5];

let doubled = numbers.map(num => num * 2);
console.log(doubled);  // [2, 4, 6, 8, 10]

// המערך המקורי לא משתנה
console.log(numbers);  // [1, 2, 3, 4, 5]

filter - סינון לפי תנאי

let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

let evens = numbers.filter(num => num % 2 === 0);
console.log(evens);  // [2, 4, 6, 8, 10]

let bigNumbers = numbers.filter(num => num > 5);
console.log(bigNumbers);  // [6, 7, 8, 9, 10]

reduce - צבירה לערך יחיד

let numbers = [1, 2, 3, 4, 5];

// סכום
let sum = numbers.reduce((acc, num) => acc + num, 0);
console.log(sum);  // 15

// מקסימום
let max = numbers.reduce((acc, num) => num > acc ? num : acc);
console.log(max);  // 5

// ספירה
let words = ["שלום", "עולם", "שלום", "לכולם"];
let count = words.reduce((acc, word) => {
    acc[word] = (acc[word] || 0) + 1;
    return acc;
}, {});
console.log(count);  // { שלום: 2, עולם: 1, לכולם: 1 }

some - האם לפחות אחד עונה על התנאי

let numbers = [1, 2, 3, 4, 5];

console.log(numbers.some(num => num > 4));   // true
console.log(numbers.some(num => num > 10));  // false

every - האם כולם עונים על התנאי

let numbers = [2, 4, 6, 8];

console.log(numbers.every(num => num % 2 === 0));  // true
console.log(numbers.every(num => num > 5));        // false

מיון (sort)

// מיון אלפביתי
let fruits = ["תפוז", "בננה", "תפוח"];
fruits.sort();
console.log(fruits);  // ["בננה", "תפוז", "תפוח"]

// מיון מספרי - צריך פונקציית השוואה!
let numbers = [30, 4, 100, 21];
numbers.sort();
console.log(numbers);  // ❌ [100, 21, 30, 4] (מיון כמחרוזות!)

numbers.sort((a, b) => a - b);
console.log(numbers);  // ✅ [4, 21, 30, 100] (עולה)

numbers.sort((a, b) => b - a);
console.log(numbers);  // ✅ [100, 30, 21, 4] (יורד)

הפיכה (reverse)

let numbers = [1, 2, 3, 4, 5];
numbers.reverse();
console.log(numbers);  // [5, 4, 3, 2, 1]

חיבור מערכים

concat

let arr1 = [1, 2];
let arr2 = [3, 4];
let combined = arr1.concat(arr2);
console.log(combined);  // [1, 2, 3, 4]

spread operator

let arr1 = [1, 2];
let arr2 = [3, 4];
let combined = [...arr1, ...arr2];
console.log(combined);  // [1, 2, 3, 4]

// עם ערכים נוספים
let extra = [0, ...arr1, 2.5, ...arr2, 5];
console.log(extra);  // [0, 1, 2, 2.5, 3, 4, 5]

המרה למחרוזת (join)

let fruits = ["תפוח", "בננה", "תפוז"];

console.log(fruits.join());      // "תפוח,בננה,תפוז"
console.log(fruits.join(" "));   // "תפוח בננה תפוז"
console.log(fruits.join(" - ")); // "תפוח - בננה - תפוז"

Destructuring

פירוק מערך למשתנים:

let fruits = ["תפוח", "בננה", "תפוז"];

// במקום:
// let first = fruits[0];
// let second = fruits[1];

// אפשר:
let [first, second] = fruits;
console.log(first);   // "תפוח"
console.log(second);  // "בננה"

// דילוג על ערכים
let [a, , c] = fruits;
console.log(c);  // "תפוז"

// עם spread
let [head, ...rest] = fruits;
console.log(head);  // "תפוח"
console.log(rest);  // ["בננה", "תפוז"]

דוגמאות מעשיות

מציאת ממוצע

const average = (arr) => {
    const sum = arr.reduce((acc, num) => acc + num, 0);
    return sum / arr.length;
};

console.log(average([80, 90, 70, 85]));  // 81.25

הסרת כפילויות

const unique = (arr) => [...new Set(arr)];

console.log(unique([1, 2, 2, 3, 3, 3]));  // [1, 2, 3]

השטחת מערך

const nested = [[1, 2], [3, 4], [5, 6]];
const flat = nested.flat();
console.log(flat);  // [1, 2, 3, 4, 5, 6]

סיכום מתודות

פעולה מתודה משנה מקור?
הוספה לסוף push() ✅
הסרה מסוף pop() ✅
הוספה להתחלה unshift() ✅
הסרה מהתחלה shift() ✅
הוספה/הסרה ממיקום splice() ✅
חיתוך slice() ❌
מיון sort() ✅
הפיכה reverse() ✅
המרה map() ❌
סינון filter() ❌
צבירה reduce() ❌
חיפוש find() ❌
חיבור concat() ❌

בדקו את עצמכם

נסו לענות לבד לפני שאתם פותחים את התשובה.

  1. מה ההבדל בין map ל-forEach?

    1. forEach מהיר פי שניים
    2. אין הבדל
    3. map משנה את המערך המקורי
    4. map מחזיר מערך חדש עם התוצאות, forEach רק מבצע פעולה ומחזיר undefined
    הצגת התשובה

    תשובה ד. map להמרה, forEach לתופעות לוואי כמו הדפסה.

  2. מה מחזיר [1, 2, 3, 4].filter(n => n % 2 === 0)?

    1. true
    2. 2
    3. [1, 3]
    4. [2, 4]
    הצגת התשובה

    תשובה ד. filter מחזיר מערך חדש עם האיברים שעבורם הפונקציה מחזירה true.

  3. איזו מתודה משנה את המערך המקורי?

    1. slice
    2. push
    3. map
    4. filter
    הצגת התשובה

    תשובה ב. push, pop, splice ו-sort משנים את המקור. map, filter ו-slice מחזירים מערך חדש.