GetGroupedOpCodes isolates change clusters by eliminating ranges with no changes. Return a generator of groups with up to n lines of context. Each group is in the same format as returned by GetOpCodes().
(n int)
| 477 | // Return a generator of groups with up to n lines of context. |
| 478 | // Each group is in the same format as returned by GetOpCodes(). |
| 479 | func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode { |
| 480 | if n < 0 { |
| 481 | n = 3 |
| 482 | } |
| 483 | codes := m.GetOpCodes() |
| 484 | if len(codes) == 0 { |
| 485 | codes = []OpCode{{'e', 0, 1, 0, 1}} |
| 486 | } |
| 487 | // Fixup leading and trailing groups if they show no changes. |
| 488 | if codes[0].Tag == 'e' { |
| 489 | c := codes[0] |
| 490 | i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 |
| 491 | codes[0] = OpCode{c.Tag, max(i1, i2-n), i2, max(j1, j2-n), j2} |
| 492 | } |
| 493 | if codes[len(codes)-1].Tag == 'e' { |
| 494 | c := codes[len(codes)-1] |
| 495 | i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 |
| 496 | codes[len(codes)-1] = OpCode{c.Tag, i1, min(i2, i1+n), j1, min(j2, j1+n)} |
| 497 | } |
| 498 | nn := n + n |
| 499 | var groups [][]OpCode |
| 500 | var group []OpCode |
| 501 | for _, c := range codes { |
| 502 | i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 |
| 503 | // End the current group and start a new one whenever |
| 504 | // there is a large range with no changes. |
| 505 | if c.Tag == 'e' && i2-i1 > nn { |
| 506 | group = append(group, OpCode{c.Tag, i1, min(i2, i1+n), |
| 507 | j1, min(j2, j1+n)}) |
| 508 | groups = append(groups, group) |
| 509 | group = []OpCode{} |
| 510 | i1, j1 = max(i1, i2-n), max(j1, j2-n) |
| 511 | } |
| 512 | group = append(group, OpCode{c.Tag, i1, i2, j1, j2}) |
| 513 | } |
| 514 | if len(group) > 0 && !(len(group) == 1 && group[0].Tag == 'e') { |
| 515 | groups = append(groups, group) |
| 516 | } |
| 517 | return groups |
| 518 | } |
| 519 | |
| 520 | // Ratio returns a measure of the sequences' similarity (float in [0,1]). |
| 521 | // |