חיפוש ]

השוואת מערכים ב‑JavaScript וב‑jQuery – מדריך למתחילים

השוואת שני מערכים ב-JavaScript או jQuery אולי נראית פשוטה, אך בפועל יש יותר מורכבות מאשר שימוש ב-== או ===. מערכים הם טיפוסי רפרנס (reference types), מה שאומר שגם אם הם מכילים את אותם ערכים בדיוק, הם לא ייחשבו שווים אלא אם הם מפנים לאותו אובייקט בזיכרון.

אם אתם רוצים לבדוק האם שני מערכים מכילים את אותם ערכים באותו סדר – עליכם להשוות בין כל איבר בנפרד.

בפוסט הזה נלמד כיצד להשוות מערכים בצורה מדויקת באמצעות JavaScript ו-jQuery. תראו מתי שיטות מובנות לא מספיקות, ואיך לטפל גם בערכים פשוטים וגם במבנים מורכבים. אם אתם חדשים בעבודה עם מערכים, כדאי לקרוא גם את המדריך המלא למערכים ב-JavaScript.

השוואת מערכים ב-JavaScript

JavaScript מציעה כמה דרכים יעילות להשוות בין מערכים, בהתאם לשאלה האם מדובר בערכים פשוטים, אובייקטים, והאם חשוב לכם סדר האיברים. השיטות האלו גם שימושיות כשאתם מסננים מערכים או מבצעים ולידציה.

למה == ו-=== לא עובדים

הנה דוגמה שממחישה מדוע השוואת רפרנס לא מספיקה:

const a = [1, 2, 3];
const b = [1, 2, 3];

console.log(a === b); // false

למרות ששני המערכים נראים זהים, הם שני אובייקטים שונים בזיכרון. לכן התוצאה היא false.

השוואה באמצעות length ו- ()every

השיטה הנפוצה ביותר להשוואת מערכים ב-JavaScript:

  • בדקו האם האורך של שני המערכים זהה
  • השוו כל איבר מול האיבר המתאים באמצעות every()
function arraysEqual(a, b) {
  return a.length === b.length && a.every((val, index) => val === b[index]);
}

const x = [1, 2, 3];
const y = [1, 2, 3];

console.log(arraysEqual(x, y)); // true

השיטה הזו מתאימה למערכים שטוחים שמכילים ערכים פשוטים. רוצים להעמיק? עיינו שוב במדריך למערכים.

השוואה מהירה עם ()JSON.stringify

דרך נוספת להשוואה מהירה של מערכים שטוחים היא להפוך אותם למחרוזת:

const a = [1, 2, 3];
const b = [1, 2, 3];

console.log(JSON.stringify(a) === JSON.stringify(b)); // true

השיטה הזו עובדת רק כש:

  • המערכים שטוחים (ללא אובייקטים מקוננים)
  • סדר האיברים חשוב

שימו לב ש-JSON.stringify() מתעלם מערכי undefined ופונקציות, ממיר NaN ל-null, ורגיש לסדר המפתחות באובייקטים. לדוגמה, JSON.stringify({a: 1, b: 2}) ו-JSON.stringify({b: 2, a: 1}) מייצרים מחרוזות שונות למרות שהאובייקטים זהים לוגית.

השוואת מערכים בלי תלות בסדר

אם סדר האיברים לא משנה לכם, מיינו עותקים של שני המערכים לפני ההשוואה:

function unorderedEqual(a, b) {
  if (a.length !== b.length) return false;
  const sortedA = [...a].sort();
  const sortedB = [...b].sort();
  return sortedA.every((val, index) => val === sortedB[index]);
}

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

שימו לב לשימוש באופרטור spread ([...a]) כדי ליצור עותקים לפני המיון. כך נמנעים משינוי המערכים המקוריים. למידע נוסף על מיון, עיינו בפוסט שלנו על מיון מערכים ב-JavaScript.

השוואת מערכים של אובייקטים

אם אתם רוצים להשוות מערכים של אובייקטים, אפשר להשתמש ב-JSON.stringify() – כל עוד סדר המפתחות קבוע:

const a = [{ id: 1 }, { id: 2 }];
const b = [{ id: 1 }, { id: 2 }];

console.log(JSON.stringify(a) === JSON.stringify(b)); // true

השתמשו בשיטה הזו רק כאשר סדר המפתחות זהה בשני האובייקטים.

להשוואה אמינה יותר של מערכים עם אובייקטים מקוננים, אפשר לכתוב פונקציית deep-equal רקורסיבית:

function deepEqual(a, b) {
  if (a === b) return true;
  if (typeof a !== typeof b) return false;
  if (Array.isArray(a) && Array.isArray(b)) {
    if (a.length !== b.length) return false;
    return a.every((val, i) => deepEqual(val, b[i]));
  }
  if (typeof a === 'object' && a !== null && b !== null) {
    const keysA = Object.keys(a);
    const keysB = Object.keys(b);
    if (keysA.length !== keysB.length) return false;
    return keysA.every(key => deepEqual(a[key], b[key]));
  }
  return false;
}

const x = [{ id: 1, meta: { active: true } }];
const y = [{ id: 1, meta: { active: true } }];

console.log(deepEqual(x, y)); // true

פונקציה זו מטפלת באובייקטים ומערכים מקוננים ללא תלות בסדר המפתחות.

השוואת מערכים באמצעות Set

אם אתם רק צריכים לדעת האם שני מערכים מכילים את אותם ערכים ייחודיים (בלי תלות בסדר ובכפילויות), אפשר להשתמש ב-Set:

function sameValues(a, b) {
  const setA = new Set(a);
  const setB = new Set(b);
  if (setA.size !== setB.size) return false;
  return [...setA].every(val => setB.has(val));
}

console.log(sameValues([1, 2, 3], [3, 1, 2]));    // true
console.log(sameValues([1, 2, 2], [1, 2]));         // true (כפילויות מתעלמות)

שיטה זו שימושית לבדיקת שייכות, אך היא לא מתחשבת בכמות הכפילויות. אם אתם צריכים להשוות כפילויות בצורה מדויקת, עיינו בפוסט שלנו על הסרת כפילויות ממערכים.

השוואת מערכים עם jQuery

jQuery לא כוללת פונקציה מובנית להשוואת מערכים, אך ניתן לבצע זאת בשילוב בין $.each() ופונקציות JavaScript רגילות. אם אתם כבר עובדים עם jQuery בהקשר של ה-DOM או טיפול ב-Events, שיטות אלו ישתלבו היטב.

השוואה ידנית עם $.each

כך ניתן להשוות בין שני מערכים בעזרת לולאה שמשווה כל ערך מול הערך המקביל:

function arraysEqual(a, b) {
  if (a.length !== b.length) return false;

  var equal = true;
  $.each(a, function(index, value) {
    if (value !== b[index]) {
      equal = false;
      return false; // עצור את הלולאה
    }
  });

  return equal;
}

var a = [1, 2, 3];
var b = [1, 2, 3];

console.log(arraysEqual(a, b)); // true

השוואה מבלי להתחשב בסדר

אם סדר האיברים לא משנה – ניתן למיין עותקים של המערכים לפני ההשוואה:

function unorderedEqual(a, b) {
  if (a.length !== b.length) return false;

  var sortedA = a.slice().sort();
  var sortedB = b.slice().sort();

  var equal = true;
  $.each(sortedA, function(index, value) {
    if (value !== sortedB[index]) {
      equal = false;
      return false;
    }
  });

  return equal;
}

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

השוואת מערכים של אובייקטים ב-jQuery

גם בפרויקטים מבוססי jQuery ניתן להשתמש ב-JSON.stringify() להשוואת מערכים של אובייקטים:

var a = [{ id: 1 }, { id: 2 }];
var b = [{ id: 1 }, { id: 2 }];

console.log(JSON.stringify(a) === JSON.stringify(b)); // true

השיטה הזו עובדת כל עוד מבנה האובייקטים וסדר המפתחות זהים.

באיזו שיטה כדאי להשתמש?

הנה סיכום מהיר לבחירת הגישה הנכונה:

  • מערכים שטוחים, הסדר חשוב – השתמשו ב-every() עם בדיקת length. פשוט, מהיר ואמין.
  • מהיר ופשוט – השתמשו ב-JSON.stringify(). קל לכתוב, אבל היזהרו עם מקרי קצה כמו undefined, NaN וסדר מפתחות באובייקטים.
  • הסדר לא חשוב – מיינו עותקים קודם, ואז השוו. השתמשו באופרטור spread או slice() כדי לא לשנות את המקוריים.
  • אובייקטים או מערכים מקוננים – כתבו פונקציית deep-equal רקורסיבית או השתמשו בספרייה מוכחת כמו Lodash (_.isEqual()).
  • שייכות ייחודית בלבד – השתמשו בהשוואה מבוססת Set כשכפילויות לא משנות.
  • פרויקטים עם jQuery – השתמשו ב-$.each() עם בדיקות ידניות אם אתם כבר בסביבת jQuery.

שאלות נפוצות

למה [1,2,3] === [1,2,3] מחזיר false ב-JavaScript?
מערכים ב-JavaScript הם אובייקטים, ואובייקטים מושווים לפי רפרנס ולא לפי ערך. גם אם שני מערכים מכילים איברים זהים, הם תופסים מיקומים שונים בזיכרון, ולכן === מחזיר false. כדי להשוות את התוכן שלהם, צריך לבדוק כל איבר בנפרד באמצעות מתודות כמו every() או JSON.stringify().
האם JSON.stringify() הוא דרך אמינה להשוות מערכים?
JSON.stringify() עובד היטב למערכים שטוחים עם ערכים פשוטים. עם זאת, יש לו מגבלות: הוא מתעלם מערכי undefined ופונקציות, ממיר NaN ל-null, ורגיש לסדר המפתחות באובייקטים. עבור מבנים מקוננים או כשסדר המפתחות עשוי להשתנות, השתמשו בפונקציית deep-equal רקורסיבית או בספרייה כמו Lodash.
איך משווים שני מערכים בלי להתחשב בסדר?
מיינו עותקים של שני המערכים קודם, ואז השוו איבר מול איבר. השתמשו באופרטור spread ([...arr].sort()) או slice() כדי לא לשנות את המקוריים. אם רק חשוב לכם שייכות ייחודית ללא ספירת כפילויות, תוכלו להשתמש בגישה מבוססת Set.
אפשר להשתמש ב-Lodash או ספריות אחרות להשוואת מערכים?
כן. המתודה _.isEqual() של Lodash מבצעת השוואה עמוקה (deep comparison) בין שני ערכים ומטפלת בכל מקרי הקצה, כולל אובייקטים מקוננים, מערכים, NaN וסדרי מפתחות שונים. זו בחירה מצוינת לקוד פרודקשן שבו צריך בדיקות שוויון עמוקות ואמינות בלי לכתוב פונקציה רקורסיבית בעצמכם.
האם sort() משנה את המערך המקורי בזמן ההשוואה?
כן, sort() משנה את המערך המקורי במקום. תמיד צרו עותק לפני המיון אם אתם רוצים לשמור על הסדר המקורי. השתמשו ב-[...arr].sort() (אופרטור spread) או arr.slice().sort() כדי למיין עותק. ב-JavaScript מודרני (ES2023+), אפשר גם להשתמש ב-arr.toSorted(), שמחזיר מערך ממוין חדש בלי לשנות את המקורי.

סיכום

השוואת מערכים דורשת יותר מסתם שימוש ב-== או ===. ב-JavaScript תוכלו להשתמש ב-every() או JSON.stringify() להשוואת מערכים שטוחים, למיין עותקים אם הסדר לא חשוב, ולכתוב פונקציה רקורסיבית למבנים מקוננים. ב-jQuery, אפשר לבצע את אותן ההשוואות בעזרת $.each() ולוגיקה ידנית.

דיון ותגובות
0 תגובות  ]

השאירו תגובה

הוסיפו קוד באמצעות הכפתורים מטה. למשל, בכדי להוסיף PHP לחצו על הכפתור PHP והוסיפו את הקוד בתוך השורטקוד. מצאתם שגיאה בפוסט? עדכנו אותנו...

Savvy WordPress Development official logo