Compare items in two sequences to find a **longest common subsequence**.
The items not in common are the items to delete or insert in a **shortest edit script**.
To maximize flexibility and minimize memory, you write **callback** functions as configuration:
**Input** function `isCommon(aIndex, bIndex)` compares items at indexes in the sequences and returns a truthy/falsey value. This package might call your function more than once for some pairs of indexes.
- Because your function encapsulates **comparison**, this package can compare items according to `===` operator, `Object.is` method, or other criterion.
- Because your function encapsulates **sequences**, this package can find differences in arrays, strings, or other data.
**Output** function `foundSubsequence(nCommon, aCommon, bCommon)` receives the number of adjacent items and starting indexes of each common subsequence. If sequences do not have common items, then this package does not call your function.
If N is the sum of lengths of sequences and L is length of a longest common subsequence, then D = N – 2L is the number of **differences** in the corresponding shortest edit script.
[_An O(ND) Difference Algorithm and Its Variations_](http://xmailserver.org/diff2.pdf) by Eugene W. Myers is fast when sequences have **few** differences.
This package implements the **linear space** variation with optimizations so it is fast even when sequences have **many** differences.
## Usage
To add this package as a dependency of a project, do either of the following:
-`npm install diff-sequences`
-`yarn add diff-sequences`
To use `diff` as the name of the default export from this package, do either of the following:
The “edit graph” analogy in the Myers paper shows the following common items:
| comparisons of common items | values |
| :------------------------------- | :--------- |
| `a[2] === b[0]` | `'c'` |
| `a[3] === b[2] && a[4] === b[3]` | `'a', 'b'` |
| `a[6] === b[4]` | `'a'` |
Various packages which implement the Myers algorithm will **always agree** on the **length** of a longest common subsequence, but might **sometimes disagree** on which **items** are in it.
## Example of callback functions to count common items
```js
// Return length of longest common subsequence according to === operator.
If N is the sum of lengths of sequences and L is length of a longest common subsequence, then N – L is length of an array of diff lines. In this example, N is 7 + 9, L is 5, and N – L is 11.
## Example of callback functions to find diff items
Here is simplified code to find changed and unchanged substrings **within adjacent changed lines** in expected and received values after a test fails in Jest:
```js
// Return diff items for strings (compatible with diff-match-patch package).
The length difference `b.length - a.length` is equal to the sum of `diffItems[i][0]` values times `diffItems[i][1]` lengths. In this example, the difference `48 - 38` is equal to the sum `10`.
Instead of formatting the changed substrings with escape codes for colors in the `foundSubsequence` function to save memory, this example spends memory to **gain flexibility** before formatting, so a separate heuristic algorithm might modify the generic array of diff items to show changes more clearly:
| `i` | `diffItems[i][0]` | `diffItems[i][1]` |
| --: | ----------------: | :---------------- |
| `6` | `-1` | `'true'` |
| `7` | `1` | `'false'` |
| `8` | `0` | `','` |
For expected and received strings of serialized data, the result of finding changed **lines**, and then finding changed **substrings** within adjacent changed lines (as in the preceding two examples) sometimes displays the changes in a more intuitive way than the result of finding changed substrings, and then splitting them into changed and unchanged lines.