README.md in hashdiff-0.3.9 vs README.md in hashdiff-0.4.0

- old
+ new

@@ -1,29 +1,29 @@ -# HashDiff [![Build Status](https://secure.travis-ci.org/liufengyun/hashdiff.svg)](http://travis-ci.org/liufengyun/hashdiff) [![Gem Version](https://badge.fury.io/rb/hashdiff.svg)](http://badge.fury.io/rb/hashdiff) +# Hashdiff [![Build Status](https://secure.travis-ci.org/liufengyun/hashdiff.svg)](http://travis-ci.org/liufengyun/hashdiff) [![Gem Version](https://badge.fury.io/rb/hashdiff.svg)](http://badge.fury.io/rb/hashdiff) -HashDiff is a ruby library to compute the smallest difference between two hashes. +Hashdiff is a ruby library to compute the smallest difference between two hashes. It also supports comparing two arrays. -HashDiff does not monkey-patch any existing class. All features are contained inside the `HashDiff` module. +Hashdiff does not monkey-patch any existing class. All features are contained inside the `Hashdiff` module. **Docs**: [Documentation](http://rubydoc.info/gems/hashdiff) __WARNING__: Don't use the library for comparing large arrays, say ~10K (see #49). -## Why HashDiff? +## Why Hashdiff? Given two Hashes A and B, sometimes you face the question: what's the smallest modification that can be made to change A into B? An algorithm that responds to this question has to do following: * Generate a list of additions, deletions and changes, so that `A + ChangeSet = B` and `B - ChangeSet = A`. * Compute recursively -- Arrays and Hashes may be nested arbitrarily in A or B. * Compute the smallest change -- it should recognize similar child Hashes or child Arrays between A and B. -HashDiff answers the question above using an opinionated approach: +Hashdiff answers the question above using an opinionated approach: * Hash can be represented as a list of (dot-syntax-path, value) pairs. For example, `{a:[{c:2}]}` can be represented as `["a[0].c", 2]`. * The change set can be represented using the dot-syntax representation. For example, `[['-', 'b.x', 3], ['~', 'b.z', 45, 30], ['+', 'b.y', 3]]`. * It compares Arrays using the [LCS(longest common subsequence)](http://en.wikipedia.org/wiki/Longest_common_subsequence_problem) algorithm. * It recognizes similar Hashes in an Array using a similarity value (0 < similarity <= 1). @@ -44,31 +44,31 @@ ```ruby a = {a:3, b:2} b = {} -diff = HashDiff.diff(a, b) +diff = Hashdiff.diff(a, b) diff.should == [['-', 'a', 3], ['-', 'b', 2]] ``` More complex hashes: ```ruby a = {a:{x:2, y:3, z:4}, b:{x:3, z:45}} b = {a:{y:3}, b:{y:3, z:30}} -diff = HashDiff.diff(a, b) +diff = Hashdiff.diff(a, b) diff.should == [['-', 'a.x', 2], ['-', 'a.z', 4], ['-', 'b.x', 3], ['~', 'b.z', 45, 30], ['+', 'b.y', 3]] ``` Arrays in hashes: ```ruby a = {a:[{x:2, y:3, z:4}, {x:11, y:22, z:33}], b:{x:3, z:45}} b = {a:[{y:3}, {x:11, z:33}], b:{y:22}} -diff = HashDiff.best_diff(a, b) +diff = Hashdiff.best_diff(a, b) diff.should == [['-', 'a[0].x', 2], ['-', 'a[0].z', 4], ['-', 'a[1].y', 22], ['-', 'b.x', 3], ['-', 'b.z', 45], ['+', 'b.y', 22]] ``` ### Patch @@ -76,22 +76,22 @@ ```ruby a = {'a' => 3} b = {'a' => {'a1' => 1, 'a2' => 2}} -diff = HashDiff.diff(a, b) -HashDiff.patch!(a, diff).should == b +diff = Hashdiff.diff(a, b) +Hashdiff.patch!(a, diff).should == b ``` unpatch example: ```ruby a = [{'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5}, {'x' => 5, 'y' => 6, 'z' => 3}, 1] b = [1, {'a' => 1, 'b' => 2, 'c' => 3, 'e' => 5}] -diff = HashDiff.diff(a, b) # diff two array is OK -HashDiff.unpatch!(b, diff).should == a +diff = Hashdiff.diff(a, b) # diff two array is OK +Hashdiff.unpatch!(b, diff).should == a ``` ### Options There are eight options available: `:delimiter`, `:similarity`, @@ -104,11 +104,11 @@ ```ruby a = {a:{x:2, y:3, z:4}, b:{x:3, z:45}} b = {a:{y:3}, b:{y:3, z:30}} -diff = HashDiff.diff(a, b, :delimiter => '\t') +diff = Hashdiff.diff(a, b, :delimiter => '\t') diff.should == [['-', 'a\tx', 2], ['-', 'a\tz', 4], ['-', 'b\tx', 3], ['~', 'b\tz', 45, 30], ['+', 'b\ty', 3]] ``` #### `:similarity` @@ -124,11 +124,11 @@ ```ruby a = {x:5, y:3.75, z:7} b = {x:6, y:3.76, z:7} -diff = HashDiff.diff(a, b, :numeric_tolerance => 0.1) +diff = Hashdiff.diff(a, b, :numeric_tolerance => 0.1) diff.should == [["~", "x", 5, 6]] ``` #### `:strip` @@ -136,11 +136,11 @@ ```ruby a = {x:5, s:'foo '} b = {x:6, s:'foo'} -diff = HashDiff.diff(a, b, :comparison => { :numeric_tolerance => 0.1, :strip => true }) +diff = Hashdiff.diff(a, b, :comparison => { :numeric_tolerance => 0.1, :strip => true }) diff.should == [["~", "x", 5, 6]] ``` #### `:case_insensitive` @@ -148,11 +148,11 @@ ```ruby a = {x:5, s:'FooBar'} b = {x:6, s:'foobar'} -diff = HashDiff.diff(a, b, :comparison => { :numeric_tolerance => 0.1, :case_insensitive => true }) +diff = Hashdiff.diff(a, b, :comparison => { :numeric_tolerance => 0.1, :case_insensitive => true }) diff.should == [["~", "x", 5, 6]] ``` #### `:array_path` @@ -162,31 +162,31 @@ ```ruby a = {x:5} b = {'x'=>6} -diff = HashDiff.diff(a, b, :array_path => true) +diff = Hashdiff.diff(a, b, :array_path => true) diff.should == [['-', [:x], 5], ['+', ['x'], 6]] ``` For cases where there are arrays in paths their index will be added to the path. ```ruby a = {x:[0,1]} b = {x:[0,2]} -diff = HashDiff.diff(a, b, :array_path => true) +diff = Hashdiff.diff(a, b, :array_path => true) diff.should == [["-", [:x, 1], 1], ["+", [:x, 1], 2]] ``` This shouldn't cause problems if you are comparing an array with a hash: ```ruby a = {x:{0=>1}} b = {x:[1]} -diff = HashDiff.diff(a, b, :array_path => true) -diff.should == [["~", [:a], [1], {0=>1}]] +diff = Hashdiff.diff(a, b, :array_path => true) +diff.should == [["~", [:x], {0=>1}, [1]]] ``` #### `:use_lcs` The :use_lcs option is used to specify whether a @@ -203,11 +203,11 @@ ```ruby a = {x: [0, 1, 2]} b = {x: [0, 2, 2, 3]} -diff = HashDiff.diff(a, b, :use_lcs => false) +diff = Hashdiff.diff(a, b, :use_lcs => false) diff.should == [["~", "x[1]", 1, 2], ["+", "x[3]", 3]] ``` #### Specifying a custom comparison method @@ -215,11 +215,11 @@ ```ruby a = {a:'car', b:'boat', c:'plane'} b = {a:'bus', b:'truck', c:' plan'} -diff = HashDiff.diff(a, b) do |path, obj1, obj2| +diff = Hashdiff.diff(a, b) do |path, obj1, obj2| case path when /a|b|c/ obj1.length == obj2.length end end @@ -231,11 +231,11 @@ ```ruby a = {a:'car', b:['boat', 'plane'] } b = {a:'bus', b:['truck', ' plan'] } -diff = HashDiff.diff(a, b) do |path, obj1, obj2| +diff = Hashdiff.diff(a, b) do |path, obj1, obj2| case path when 'b[*]' obj1.length == obj2.length end end @@ -253,15 +253,20 @@ ```ruby a = {a:'car', b:['boat', 'plane'] } b = {a:'car', b:['plane', 'boat'] } -HashDiff.diff(a, b) => [["+", "b[0]", "plane"], ["-", "b[2]", "plane"]] +Hashdiff.diff(a, b) => [["+", "b[0]", "plane"], ["-", "b[2]", "plane"]] b[:b].sort! -HashDiff.diff(a, b) => [] +Hashdiff.diff(a, b) => [] ``` +## Maintainers + +- Krzysztof Rybka ([@krzysiek1507](https://github.com/krzysiek1507)) +- Fengyun Liu ([@liufengyun](https://github.com/liufengyun)) + ## License -HashDiff is distributed under the MIT-LICENSE. +Hashdiff is distributed under the MIT-LICENSE.