@@ -38,6 +38,11 @@ public JsonDiffPatch(Options options)
38
38
/// <returns>JSON Patch Document</returns>
39
39
public JToken Diff ( JToken left , JToken right )
40
40
{
41
+
42
+ var objectHash = this . _options . ObjectHash ;
43
+ var itemMatch = new DefaultItemMatch ( objectHash ) ;
44
+
45
+
41
46
if ( left == null )
42
47
left = new JValue ( "" ) ;
43
48
if ( right == null )
@@ -67,7 +72,7 @@ public JToken Diff(JToken left, JToken right)
67
72
: null ;
68
73
}
69
74
70
- if ( ! JToken . DeepEquals ( left , right ) )
75
+ if ( ! itemMatch . Match ( left , right ) )
71
76
{
72
77
return new JArray ( left , right ) ;
73
78
}
@@ -371,91 +376,116 @@ private JObject ObjectDiff(JObject left, JObject right)
371
376
}
372
377
373
378
private JObject ArrayDiff ( JArray left , JArray right )
374
- {
375
- var result = JObject . Parse ( @"{ ""_t"": ""a"" }" ) ;
376
-
377
- int commonHead = 0 ;
378
- int commonTail = 0 ;
379
-
380
- if ( JToken . DeepEquals ( left , right ) )
381
- return null ;
382
-
383
- // Find common head
384
- while ( commonHead < left . Count
385
- && commonHead < right . Count
386
- && JToken . DeepEquals ( left [ commonHead ] , right [ commonHead ] ) )
387
- {
388
- commonHead ++ ;
389
- }
390
-
391
- // Find common tail
392
- while ( commonTail + commonHead < left . Count
393
- && commonTail + commonHead < right . Count
394
- && JToken . DeepEquals ( left [ left . Count - 1 - commonTail ] , right [ right . Count - 1 - commonTail ] ) )
395
- {
396
- commonTail ++ ;
397
- }
398
-
399
- if ( commonHead + commonTail == left . Count )
400
- {
401
- // Trivial case, a block (1 or more consecutive items) was added
402
- for ( int index = commonHead ; index < right . Count - commonTail ; ++ index )
403
- {
404
- result [ $ "{ index } "] = new JArray ( right [ index ] ) ;
405
- }
406
-
407
- return result ;
408
- }
409
- if ( commonHead + commonTail == right . Count )
410
- {
411
- // Trivial case, a block (1 or more consecutive items) was removed
412
- for ( int index = commonHead ; index < left . Count - commonTail ; ++ index )
413
- {
414
- result [ $ "_{ index } "] = new JArray ( left [ index ] , 0 , ( int ) DiffOperation . Deleted ) ;
415
- }
416
-
417
- return result ;
418
- }
419
-
420
- // Complex Diff, find the LCS (Longest Common Subsequence)
421
- List < JToken > trimmedLeft = left . ToList ( ) . GetRange ( commonHead , left . Count - commonTail - commonHead ) ;
422
- List < JToken > trimmedRight = right . ToList ( ) . GetRange ( commonHead , right . Count - commonTail - commonHead ) ;
423
- Lcs lcs = Lcs . Get ( trimmedLeft , trimmedRight ) ;
424
-
425
- for ( int index = commonHead ; index < left . Count - commonTail ; ++ index )
426
- {
427
- if ( lcs . Indices1 . IndexOf ( index - commonHead ) < 0 )
428
- {
429
- // Removed
430
- result [ $ "_{ index } "] = new JArray ( left [ index ] , 0 , ( int ) DiffOperation . Deleted ) ;
431
- }
432
- }
433
-
434
- for ( int index = commonHead ; index < right . Count - commonTail ; index ++ )
435
- {
436
- int indexRight = lcs . Indices2 . IndexOf ( index - commonHead ) ;
437
-
438
- if ( indexRight < 0 )
439
- {
440
- // Added
441
- result [ $ "{ index } "] = new JArray ( right [ index ] ) ;
442
- }
443
- else
444
- {
445
- int li = lcs . Indices1 [ indexRight ] + commonHead ;
446
- int ri = lcs . Indices2 [ indexRight ] + commonHead ;
447
-
448
- JToken diff = Diff ( left [ li ] , right [ ri ] ) ;
449
-
450
- if ( diff != null )
451
- {
452
- result [ $ "{ index } "] = diff ;
453
- }
454
- }
455
- }
456
-
457
- return result ;
458
- }
379
+ {
380
+ var objectHash = this . _options . ObjectHash ;
381
+ var itemMatch = new DefaultItemMatch ( objectHash ) ;
382
+ var result = JObject . Parse ( @"{ ""_t"": ""a"" }" ) ;
383
+
384
+ int commonHead = 0 ;
385
+ int commonTail = 0 ;
386
+
387
+ if ( itemMatch . Match ( left , right ) )
388
+ return null ;
389
+
390
+ var childContext = new List < JToken > ( ) ;
391
+
392
+ // Find common head
393
+ while ( commonHead < left . Count
394
+ && commonHead < right . Count
395
+ && itemMatch . Match ( left [ commonHead ] , right [ commonHead ] ) )
396
+ {
397
+ var index = commonHead ;
398
+ var child = Diff ( left [ index ] , right [ index ] ) ;
399
+ if ( child != null )
400
+ {
401
+ result [ $ "{ index } "] = child ;
402
+ }
403
+ commonHead ++ ;
404
+ }
405
+
406
+ // Find common tail
407
+ while ( commonTail + commonHead < left . Count
408
+ && commonTail + commonHead < right . Count
409
+ && itemMatch . Match ( left [ left . Count - 1 - commonTail ] , right [ right . Count - 1 - commonTail ] ) )
410
+ {
411
+ var index1 = left . Count - 1 - commonTail ;
412
+ var index2 = right . Count - 1 - commonTail ;
413
+ var child = Diff ( left [ index1 ] , right [ index2 ] ) ;
414
+ if ( child != null )
415
+ {
416
+ result [ $ "{ index2 } "] = child ;
417
+ }
418
+ commonTail ++ ;
419
+ }
420
+
421
+ if ( commonHead + commonTail == left . Count )
422
+ {
423
+ // Trivial case, a block (1 or more consecutive items) was added
424
+ for ( int index = commonHead ; index < right . Count - commonTail ; ++ index )
425
+ {
426
+ result [ $ "{ index } "] = new JArray ( right [ index ] ) ;
427
+ }
428
+
429
+ return result ;
430
+ }
431
+ if ( commonHead + commonTail == right . Count )
432
+ {
433
+ // Trivial case, a block (1 or more consecutive items) was removed
434
+ for ( int index = commonHead ; index < left . Count - commonTail ; ++ index )
435
+ {
436
+ if ( result . ContainsKey ( index . ToString ( ) ) )
437
+ {
438
+ result . Remove ( index . ToString ( ) ) ;
439
+ }
440
+ result [ $ "_{ index } "] = new JArray ( left [ index ] , 0 , ( int ) DiffOperation . Deleted ) ;
441
+ }
442
+
443
+ return result ;
444
+ }
445
+
446
+ // Complex Diff, find the LCS (Longest Common Subsequence)
447
+ List < JToken > trimmedLeft = left . ToList ( ) . GetRange ( commonHead , left . Count - commonTail - commonHead ) ;
448
+ List < JToken > trimmedRight = right . ToList ( ) . GetRange ( commonHead , right . Count - commonTail - commonHead ) ;
449
+ Lcs lcs = Lcs . Get ( trimmedLeft , trimmedRight , itemMatch ) ;
450
+
451
+ for ( int index = commonHead ; index < left . Count - commonTail ; ++ index )
452
+ {
453
+ if ( lcs . Indices1 . IndexOf ( index - commonHead ) < 0 )
454
+ {
455
+ // Removed
456
+ if ( result . ContainsKey ( index . ToString ( ) ) )
457
+ {
458
+ result . Remove ( index . ToString ( ) ) ;
459
+ }
460
+ result [ $ "_{ index } "] = new JArray ( left [ index ] , 0 , ( int ) DiffOperation . Deleted ) ;
461
+ }
462
+ }
463
+
464
+ for ( int index = commonHead ; index < right . Count - commonTail ; index ++ )
465
+ {
466
+ int indexRight = lcs . Indices2 . IndexOf ( index - commonHead ) ;
467
+
468
+ if ( indexRight < 0 )
469
+ {
470
+ // Added
471
+ result [ $ "{ index } "] = new JArray ( right [ index ] ) ;
472
+ }
473
+ else
474
+ {
475
+ int li = lcs . Indices1 [ indexRight ] + commonHead ;
476
+ int ri = lcs . Indices2 [ indexRight ] + commonHead ;
477
+
478
+ JToken diff = Diff ( left [ li ] , right [ ri ] ) ;
479
+
480
+ if ( diff != null )
481
+ {
482
+ result [ $ "{ index } "] = diff ;
483
+ }
484
+ }
485
+ }
486
+
487
+ return result ;
488
+ }
459
489
460
490
private JObject ObjectPatch ( JObject obj , JObject patch )
461
491
{
0 commit comments