Documentation ¶
Overview ¶
Diff2 is a package for finding the differences between two sequences.
Diff2 uses a sequence matcher based on a slightly simplified version of Python's difflib sequence matcher.
Thanks to generics Diff2 can compare any two slices of comparables. (Although comparing float sequences is not recommended.) And using a key function it can also compare two slices of structs.
See New for how to create a Diff value and NewKeyFn for how to create a DiffKeyFn value which can be used to compare sequences of structs.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var Version string
Functions ¶
This section is empty.
Types ¶
type Block ¶
type Block[T comparable] struct { Tag Tag Aitems []T Bitems []T }
type BlockKeyFn ¶
func (*BlockKeyFn[T]) Items ¶
func (me *BlockKeyFn[T]) Items() []T
type Diff ¶
type Diff[T comparable] struct { A []T B []T // contains filtered or unexported fields }
func New ¶
func New[T comparable](a, b []T) *Diff[T]
New returns a Diff value based on the provided a and b slices. These slices are only ever read and may be accessed as .A and .B. After creating a Diff, call [Blocks] (or [Spans]) to see the differences.
func (*Diff[T]) Blocks ¶
Blocks returns a sequence of Block values representing how to go from a to b. Each block has a Tag and a sequence of A's and B's items. This is the easiest method for seeing the differences in two sequences. See also [Spans].
Example (Changesnoreplace) ¶
a := strings.Fields("the quick brown fox jumped over the lazy dogs") b := strings.Fields("a quick red fox jumped over some lazy hogs") diff := New(a, b) blocks := diff.Blocks() for _, block := range blocks { if block.Tag != Equal { if block.Tag == Replace { fmt.Println(Delete, strings.Join(block.Aitems, "")) fmt.Println(Insert, strings.Join(block.Bitems, "")) } else { fmt.Println(block.Tag, strings.Join(block.Items(), " ")) } } }
Output: - the + a - brown + red - the + some - dogs + hogs
Example (Changesonly) ¶
a := strings.Fields("the quick brown fox jumped over the lazy dogs") b := strings.Fields("a quick red fox jumped over some lazy hogs") diff := New(a, b) blocks := diff.Blocks() for _, block := range blocks { if block.Tag != Equal { fmt.Println(block.Tag, strings.Join(block.Items(), " ")) } }
Output: % a % red % some % hogs
Example (Common) ¶
a := strings.Fields("foo\nbar\nbaz\nquux") b := strings.Fields("foo\nbaz\nbar\nquux") diff := New(a, b) blocks := diff.Blocks() for _, block := range blocks { fmt.Println(block.Tag, strings.Join(block.Items(), " ")) }
Output: = foo + baz = bar - baz = quux
Example (Ints) ¶
a := []int{1, 2, 3, 4, 5, 6} b := []int{2, 3, 5, 7} diff := New(a, b) blocks := diff.Blocks() for _, block := range blocks { fmt.Println(block.Tag, gong.StringForSlice(block.Items())) }
Output: - 1 = 2 3 - 4 = 5 % 7
Example (Strings) ¶
a := strings.Fields("the quick brown fox jumped over the lazy dogs") b := strings.Fields("a quick red fox jumped over some lazy hogs") diff := New(a, b) blocks := diff.Blocks() for _, block := range blocks { fmt.Println(block.Tag, strings.Join(block.Items(), " ")) }
Output: % a = quick % red = fox jumped over % some = lazy % hogs
type DiffKeyFn ¶
type DiffKeyFn[T any] struct { A []T B []T // contains filtered or unexported fields }
func NewKeyFn ¶
NewKeyFn returns a DiffKeyFn value based on the provided a and b slices. These slices are only ever read and may be accessed as .A and .B. After creating a DiffKeyFn, call [Blocks] (or [Spans]) to see the differences.
func (*DiffKeyFn[T]) Blocks ¶
func (me *DiffKeyFn[T]) Blocks() []BlockKeyFn[T]
Blocks returns a sequence of BlockKeyFn values representing how to go from a to b. Each block has a Tag and a sequence of A's and B's items. This is the easiest method for seeing the differences in two sequences. See also [Spans].
Example (Namekey) ¶
/* type Place struct { x int y int name string } func newPlace(x, y int, name string) Place { return Place{x: x, y: y, name: name} } func (me *Place) String() string { return fmt.Sprintf("Place{%d,%d,%q}", me.x, me.y, me.name) } */ame) } */ a := []Place{newPlace(1, 2, "foo"), newPlace(3, 4, "bar"), newPlace(5, 6, "baz"), newPlace(7, 8, "quux")} b := []Place{newPlace(1, 2, "foo"), newPlace(6, 2, "baz"), newPlace(3, 4, "bar"), newPlace(7, 8, "quux")} diff := NewKeyFn(a, b, func(p Place) string { return p.name }) blocks := diff.Blocks() for _, block := range blocks { for _, item := range block.Items() { fmt.Println(block.Tag, item.String()) } }
Output: = Place{1,2,"foo"} + Place{6,2,"baz"} = Place{3,4,"bar"} - Place{5,6,"baz"} = Place{7,8,"quux"}
Example (Xkey) ¶
// a: [1 3 5 7] // b: [1 6 3 7] a := []Place{newPlace(1, 2, "foo"), newPlace(3, 4, "bar"), newPlace(5, 6, "baz"), newPlace(7, 8, "quux")} b := []Place{newPlace(1, 2, "foo"), newPlace(6, 2, "bar"), newPlace(3, 4, "baz"), newPlace(7, 8, "quux")} diff := NewKeyFn(a, b, func(p Place) string { return strconv.Itoa(p.x) }) blocks := diff.Blocks() for _, block := range blocks { for _, item := range block.Items() { fmt.Println(block.Tag, item.String()) } }
Output: = Place{1,2,"foo"} + Place{6,2,"bar"} = Place{3,4,"baz"} - Place{5,6,"baz"} = Place{7,8,"quux"}