Permalink
Browse files

Merge pull request #2 from nigelzor/better-equality

Improve comparision of arrays with repeated or empty elements
  • Loading branch information...
andreyvit committed Apr 24, 2013
2 parents 63712d8 + 6ba4bae commit 0d3251d0ed68078ec29f681bdd77a82b3c7a15db
Showing with 21 additions and 6 deletions.
  1. +9 −6 lib/index.iced
  2. +12 −0 test/diff_test.coffee
View
@@ -30,7 +30,7 @@ objectDiff = (obj1, obj2) ->
score += Math.min(20, Math.max(-10, subscore / 5)) # BATMAN!
if Object.keys(result).length is 0
- [score, result] = [100 * Object.keys(obj1).length, undefined]
+ [score, result] = [100 * Math.max(Object.keys(obj1).length, 0.5), undefined]
else
score = Math.max(0, score)
@@ -39,25 +39,28 @@ objectDiff = (obj1, obj2) ->
return [score, result]
-findMatchingObject = (item, fuzzyOriginals) ->
+findMatchingObject = (item, index, fuzzyOriginals) ->
# console.log "findMatchingObject: " + JSON.stringify({item, fuzzyOriginals}, null, 2)
bestMatch = null
+ matchIndex = 0
for own key, candidate of fuzzyOriginals when key isnt '__next'
+ indexDistance = Math.abs(matchIndex - index)
if extendedTypeOf(item) == extendedTypeOf(candidate)
score = diffScore(item, candidate)
- if !bestMatch || score > bestMatch.score
- bestMatch = { score, key }
+ if !bestMatch || score > bestMatch.score || (score == bestMatch.score && indexDistance < bestMatch.indexDistance)
+ bestMatch = { score, key, indexDistance }
+ matchIndex++
# console.log "findMatchingObject result = " + JSON.stringify(bestMatch, null, 2)
bestMatch
scalarize = (array, originals, fuzzyOriginals) ->
- for item in array
+ for item, index in array
if isScalar item
item
- else if fuzzyOriginals && (bestMatch = findMatchingObject(item, fuzzyOriginals)) && bestMatch.score > 40
+ else if fuzzyOriginals && (bestMatch = findMatchingObject(item, index, fuzzyOriginals)) && bestMatch.score > 40
originals[bestMatch.key] = item
bestMatch.key
else
View
@@ -19,6 +19,9 @@ describe 'diff', ->
describe 'with objects', ->
+ it "should return undefined for two empty objects", ->
+ assert.deepEqual undefined, diff({ }, { })
+
it "should return undefined for two objects with identical contents", ->
assert.deepEqual undefined, diff({ foo: 42, bar: 10 }, { foo: 42, bar: 10 })
@@ -56,6 +59,15 @@ describe 'diff', ->
it "should return undefined for two arrays with identical contents", ->
assert.deepEqual undefined, diff([{ foo: 10 }, { foo: 20 }, { foo: 30 }], [{ foo: 10 }, { foo: 20 }, { foo: 30 }])
+ it "should return undefined for two arrays with identical, empty object contents", ->
+ assert.deepEqual undefined, diff([{ }], [{ }])
+
+ it "should return undefined for two arrays with identical, empty array contents", ->
+ assert.deepEqual undefined, diff([[]], [[]])
+
+ it "should return undefined for two arrays with identical, repeated contents", ->
+ assert.deepEqual undefined, diff([{ a: 1, b: 2 }, { a: 1, b: 2 }], [{ a: 1, b: 2 }, { a: 1, b: 2 }])
+
it "should return [..., ['-', <removed item>], ...] for two arrays when the second array is missing a value", ->
assert.deepEqual [[' '], ['-', { foo: 20 }], [' ']], diff([{ foo: 10 }, { foo: 20 }, { foo: 30 }], [{ foo: 10 }, { foo: 30 }])

0 comments on commit 0d3251d

Please sign in to comment.