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

