לדלג לתוכן

2.5 מערכים פתרון

פתרון - מערכים

פתרון תרגיל 1

const animals = ["dog", "cat", "fish", "bird", "hamster"];

// 1. add "rabbit" to end
animals.push("rabbit");
console.log(animals); // ["dog", "cat", "fish", "bird", "hamster", "rabbit"]

// 2. add "turtle" to beginning
animals.unshift("turtle");
console.log(animals); // ["turtle", "dog", "cat", "fish", "bird", "hamster", "rabbit"]

// 3. remove last element
animals.pop();
console.log(animals); // ["turtle", "dog", "cat", "fish", "bird", "hamster"]

// 4. remove first element
animals.shift();
console.log(animals); // ["dog", "cat", "fish", "bird", "hamster"]

// 5. replace "fish" with "goldfish"
const fishIndex = animals.indexOf("fish");
animals[fishIndex] = "goldfish";
console.log(animals); // ["dog", "cat", "goldfish", "bird", "hamster"]

// 6. print length
console.log(animals.length); // 5

// 7. print last element
console.log(animals.at(-1)); // "hamster"

פתרון תרגיל 2

const colors = ["red", "green", "blue", "yellow", "purple"];

// 1. remove "green" and "blue" (index 1, count 2)
colors.splice(1, 2);
console.log(colors); // ["red", "yellow", "purple"]

// 2. add "orange" and "pink" at index 1
colors.splice(1, 0, "orange", "pink");
console.log(colors); // ["red", "orange", "pink", "yellow", "purple"]

// 3. add "white" at the beginning using splice
colors.splice(0, 0, "white");
console.log(colors); // ["white", "red", "orange", "pink", "yellow", "purple"]

פתרון תרגיל 3

const scores = [85, 92, 78, 95, 88, 73, 91, 82, 95, 67];

// 1. does 95 exist?
console.log(scores.includes(95)); // true

// 2. index of 88
console.log(scores.indexOf(88)); // 4

// 3. first score greater than 90
console.log(scores.find(s => s > 90)); // 92

// 4. index of first score less than 75
console.log(scores.findIndex(s => s < 75)); // 5 (73)

// 5. how many times does 95 appear
let count = 0;
for (const score of scores) {
    if (score === 95) {
        count++;
    }
}
console.log(`95 appears ${count} times`); // "95 appears 2 times"

פתרון תרגיל 4

const prices = [99.99, 5.50, 25.00, 150.00, 3.99, 49.95];

// a. cheap to expensive
prices.sort((a, b) => a - b);
console.log(prices); // [3.99, 5.5, 25, 49.95, 99.99, 150]

// b. expensive to cheap
prices.sort((a, b) => b - a);
console.log(prices); // [150, 99.99, 49.95, 25, 5.5, 3.99]

const students = [
    { name: "Charlie", grade: 85 },
    { name: "Alice", grade: 92 },
    { name: "Eve", grade: 78 },
    { name: "Bob", grade: 92 },
    { name: "Diana", grade: 88 }
];

// c. sort by grade (high to low)
students.sort((a, b) => b.grade - a.grade);
console.log(students);
// Alice (92), Bob (92), Diana (88), Charlie (85), Eve (78)

// d. sort by name (alphabetical)
students.sort((a, b) => a.name.localeCompare(b.name));
console.log(students);
// Alice, Bob, Charlie, Diana, Eve

פתרון תרגיל 5

// Part A - basic operations
const numbers = [10, 20, 30, 40, 50];
numbers.push(60);
numbers.unshift(5);
const last = numbers.pop();
console.log(`Last: ${last}`);              // "Last: 60"
console.log(`Length: ${numbers.length}`);   // "Length: 6"
console.log(`Contains 30: ${numbers.includes(30)}`); // "Contains 30: true"

// Part B - slicing
const fruits = ["apple", "banana", "cherry", "date", "elderberry"];
const firstThree = fruits.slice(0, 3);
const lastTwo = fruits.slice(-2);
const middle = fruits.slice(1, 4);
console.log(firstThree); // ["apple", "banana", "cherry"]
console.log(lastTwo);     // ["date", "elderberry"]
console.log(middle);      // ["banana", "cherry", "date"]

// Part C - find even numbers (no list comprehension in JS)
const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const evens = [];
for (const n of nums) {
    if (n % 2 === 0) {
        evens.push(n);
    }
}
console.log(evens); // [2, 4, 6, 8, 10]

// or using filter (will learn in next lesson):
// const evens = nums.filter(n => n % 2 === 0);

שינויים מפייתון:
- append הפך ל-push
- insert(0, x) הפך ל-unshift
- len() הפך ל-.length
- x in arr הפך ל-arr.includes(x)
- arr[:3] הפך ל-arr.slice(0, 3)
- arr[-2:] הפך ל-arr.slice(-2)
- list comprehension הפך ללולאה עם push

פתרון תרגיל 6

א. חיבור עם 0 באמצע:

const left = [1, 2, 3];
const right = [7, 8, 9];
const combined = [...left, 0, ...right];
console.log(combined); // [1, 2, 3, 0, 7, 8, 9]

ב. היפוך מילים:

const sentence = "JavaScript is really fun";
const reversed = sentence.split(" ").reverse().join(" ");
console.log(reversed); // "fun really is JavaScript"

שבירה של הצעדים:
1. split(" ") - ["JavaScript", "is", "really", "fun"]
2. reverse() - ["fun", "really", "is", "JavaScript"]
3. join(" ") - "fun really is JavaScript"

פתרון תרגיל 7

function removeDuplicates(arr) {
    const result = [];
    for (const item of arr) {
        if (!result.includes(item)) {
            result.push(item);
        }
    }
    return result;
}

console.log(removeDuplicates([1, 2, 2, 3, 4, 4, 5]));    // [1, 2, 3, 4, 5]
console.log(removeDuplicates(["a", "b", "a", "c", "b"])); // ["a", "b", "c"]

// bonus: using Set (much shorter)
const removeDuplicates2 = arr => [...new Set(arr)];

פתרון תרגיל 8

פתרון פשוט:

function mergeSorted(arr1, arr2) {
    return [...arr1, ...arr2].sort((a, b) => a - b);
}

פתרון אתגר (בלי sort):

function mergeSorted(arr1, arr2) {
    const result = [];
    let i = 0;
    let j = 0;

    while (i < arr1.length && j < arr2.length) {
        if (arr1[i] <= arr2[j]) {
            result.push(arr1[i]);
            i++;
        } else {
            result.push(arr2[j]);
            j++;
        }
    }

    // add remaining elements
    while (i < arr1.length) {
        result.push(arr1[i]);
        i++;
    }

    while (j < arr2.length) {
        result.push(arr2[j]);
        j++;
    }

    return result;
}

console.log(mergeSorted([1, 3, 5, 7], [2, 4, 6, 8])); // [1, 2, 3, 4, 5, 6, 7, 8]
console.log(mergeSorted([1, 5, 9], [2, 3]));            // [1, 2, 3, 5, 9]
console.log(mergeSorted([], [1, 2, 3]));                 // [1, 2, 3]

פתרון תרגיל 9

const matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
];

// 1. print row by row
for (const row of matrix) {
    console.log(row.join(" "));
}
// "1 2 3"
// "4 5 6"
// "7 8 9"

// 2. sum of each row
for (let i = 0; i < matrix.length; i++) {
    let rowSum = 0;
    for (const cell of matrix[i]) {
        rowSum += cell;
    }
    console.log(`Row ${i} sum: ${rowSum}`);
}
// "Row 0 sum: 6"
// "Row 1 sum: 15"
// "Row 2 sum: 24"

// 3. diagonal sum
let diagonalSum = 0;
for (let i = 0; i < matrix.length; i++) {
    diagonalSum += matrix[i][i];
}
console.log(`Diagonal sum: ${diagonalSum}`); // 15 (1 + 5 + 9)

// 4. check if number exists in matrix
function matrixIncludes(matrix, target) {
    for (const row of matrix) {
        if (row.includes(target)) {
            return true;
        }
    }
    return false;
}

console.log(matrixIncludes(matrix, 5));  // true
console.log(matrixIncludes(matrix, 10)); // false

פתרון תרגיל 10

function addTask(tasks, task) {
    tasks.push(task);
}

function removeTask(tasks, index) {
    if (index < 0 || index >= tasks.length) {
        console.log("Invalid index");
        return;
    }
    tasks.splice(index, 1);
}

function moveTask(tasks, fromIndex, toIndex) {
    if (fromIndex < 0 || fromIndex >= tasks.length) {
        console.log("Invalid from index");
        return;
    }
    if (toIndex < 0 || toIndex >= tasks.length) {
        console.log("Invalid to index");
        return;
    }

    // remove the task from its current position
    const task = tasks.splice(fromIndex, 1)[0];
    // insert it at the new position
    tasks.splice(toIndex, 0, task);
}

function printTasks(tasks) {
    if (tasks.length === 0) {
        console.log("No tasks!");
        return;
    }
    for (let i = 0; i < tasks.length; i++) {
        console.log(`${i + 1}. ${tasks[i]}`);
    }
}

// testing
const myTasks = [];
addTask(myTasks, "Learn JavaScript");
addTask(myTasks, "Practice arrays");
addTask(myTasks, "Build a project");
printTasks(myTasks);
// 1. Learn JavaScript
// 2. Practice arrays
// 3. Build a project

console.log("---");

moveTask(myTasks, 2, 0);
printTasks(myTasks);
// 1. Build a project
// 2. Learn JavaScript
// 3. Practice arrays

console.log("---");

removeTask(myTasks, 1);
printTasks(myTasks);
// 1. Build a project
// 2. Practice arrays

נקודות עיקריות:
- splice(fromIndex, 1) מסיר איבר אחד ומחזיר מערך עם האיבר שהוסר - לכן [0] כדי לקבל את הערך
- splice(toIndex, 0, task) מוסיף את האיבר בלי למחוק כלום
- בדיקת גבולות (guard clauses) חשובה כדי למנוע באגים

תשובות לשאלות

  1. slice לא משנה את המערך המקורי ומחזירה עותק של חלק מהמערך. splice משנה את המערך המקורי - מוסיף, מסיר, או מחליף איברים.

  2. sort() ממיר כברירת מחדל הכל למחרוזות ומשווה לפי סדר אלפביתי. "10" מתחיל ב-"1" ו-"100" גם, ושניהם באים לפני "5" אלפביתית. כדי למיין מספרים נכון צריך sort((a, b) => a - b).

  3. העתקה שטחית מעתיקה את האיברים ברמה הראשונה בלבד. אם יש אובייקטים או מערכים מקוננים, היא מעתיקה את ההפניה אליהם (לא עותק שלהם). העתקה עמוקה (structuredClone) מעתיקה הכל, כולל מבנים מקוננים. צריך העתקה עמוקה כשיש מערכים בתוך מערכים או אובייקטים מקוננים.

  4. indexOf מחפש ערך מסוים ומחזיר את האינדקס שלו (או -1). findIndex מקבל פונקציית callback ומחפש את האיבר הראשון שעונה על תנאי. indexOf פשוט יותר לחיפוש ערך בודד, findIndex גמיש יותר לחיפוש לפי תנאי.

  5. const מונע שינוי של ההפניה (reference) - אי אפשר לעשות arr = [4,5,6]. אבל אפשר לשנות את התוכן של המערך (push, pop, splice וכו'). const אומר "המשתנה הזה יצביע תמיד על אותו מערך", לא "המערך לא ישתנה".