ภาพรวม
บทความนี้สาธิตวิธีหา Element ที่อยู่ในอาร์เรย์ใดอาร์เรย์หนึ่ง แต่ไม่อยู่ในทั้งสอง (Symmetric Difference)
ตัวอย่าง
arr1 = [12, 54, 2, 4, 6, 34, 3]
arr2 = [54, 2, 5, 12, 4, 1, 3, 34]
Difference: [6, 5, 1] (6 อยู่แค่ arr1, 5,1 อยู่แค่ arr2)
การนำไปใช้
const difference = (first, second) => {
const res = [];
for (let i = 0; i < first.length; i++) {
if (second.indexOf(first[i]) === -1) res.push(first[i]);
}
for (let j = 0; j < second.length; j++) {
if (first.indexOf(second[j]) === -1) res.push(second[j]);
}
return res;
};
console.log(difference(arr1, arr2));
ผลลัพธ์
[6, 5, 1]
วิธีการทันสมัย (Set Operations)
const symmetricDifference = (arr1, arr2) => {
const set1 = new Set(arr1);
const set2 = new Set(arr2);
const diff1 = [...set1].filter(x => !set2.has(x));
const diff2 = [...set2].filter(x => !set1.has(x));
return [...diff1, ...diff2];
};
// One-liner
const symDiff = (a, b) => [...new Set(a)].filter(x => !new Set(b).has(x))
.concat([...new Set(b)].filter(x => !new Set(a).has(x)));
Lodash / Utility Libraries
// Lodash
_.xor(arr1, arr2); // Symmetric Difference
_.difference(arr1, arr2); // In arr1 but not arr2
_.union(arr1, arr2); // Union
_.intersection(arr1, arr2); // Intersection
Complexity
| Method | Time | Space |
|---|---|---|
| Nested Loop (indexOf) | O(n×m) | O(k) |
| Set + Filter | O(n+m) | O(n+m) |
| Map Counting | O(n+m) | O(n+m) |
การประยุกต์ใช้
- Data Synchronization: หา Records ที่ต่างกัน
- Version Control: File Differences
- Set Theory Operations
- Testing: Compare Expected vs Actual
- Database: Row-level Diff
Preserve Order และ Duplicates
const symmetricDifferenceWithDuplicates = (arr1, arr2) => {
const count = new Map();
for (const x of arr1) count.set(x, (count.get(x) || 0) + 1);
for (const x of arr2) count.set(x, (count.get(x) || 0) - 1);
const result = [];
for (const x of arr1) {
if (count.get(x) > 0) { result.push(x); count.set(x, count.get(x) - 1); }
}
for (const x of arr2) {
if (count.get(x) < 0) { result.push(x); count.set(x, count.get(x) + 1); }
}
return result;
};