Skip to content

Commit 6ac8ade

Browse files
authored
fix(util/loose-equal): handle comparing sparse arrays (#2813)
1 parent a23c53f commit 6ac8ade

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

src/utils/loose-equal.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@ function isDate(obj) {
55
return obj instanceof Date
66
}
77

8+
// Assumes both a and b are arrays!
9+
// Handles when arrays are "sparse" (array.every(...) doesn't handle sparse)
10+
function compareArrays(a, b) {
11+
if (a.length !== b.length) {
12+
return false
13+
}
14+
let equal = true
15+
for (let i = 0; equal && i < a.length; i++) {
16+
equal = looseEqual(a[i], b[i])
17+
}
18+
return equal
19+
}
20+
821
/**
922
* Check if two values are loosely equal - that is,
1023
* if they are plain objects, do they have the same shape?
@@ -22,9 +35,7 @@ function looseEqual(a, b) {
2235
aValidType = isArray(a)
2336
bValidType = isArray(b)
2437
if (aValidType || bValidType) {
25-
return aValidType && bValidType
26-
? a.length === b.length && a.every((e, i) => looseEqual(e, b[i]))
27-
: false
38+
return aValidType && bValidType ? compareArrays(a, b) : false
2839
}
2940
aValidType = isObject(a)
3041
bValidType = isObject(b)

src/utils/loose-equal.spec.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,4 +175,22 @@ describe('looseEqual', () => {
175175
expect(looseEqual(null, false)).toBe(false)
176176
expect(looseEqual(undefined, false)).toBe(false)
177177
})
178+
179+
it('compares sparse arrays correctly', () => {
180+
// The following arrays all have a length of 3
181+
// But the first two are "sparse"
182+
const arr1 = []
183+
arr1[2] = true
184+
const arr2 = []
185+
arr2[2] = true
186+
const arr3 = [false, false, true]
187+
const arr4 = [undefined, undefined, true]
188+
189+
expect(looseEqual(arr1, arr2)).toBe(true)
190+
expect(looseEqual(arr2, arr1)).toBe(true)
191+
expect(looseEqual(arr1, arr3)).toBe(false)
192+
expect(looseEqual(arr3, arr1)).toBe(false)
193+
expect(looseEqual(arr1, arr4)).toBe(true)
194+
expect(looseEqual(arr4, arr1)).toBe(true)
195+
})
178196
})

0 commit comments

Comments
 (0)