linear-list-diff

1.0.2 • Public • Published

linear-list-diff

A linear-complexity list diff for diffing 2 lists. It is simple & comprehensive, and takes only 80 lines.

This algorithm is used for diffing 2 lists of children of 2 vtree, thus if neither of the 2 lists contain any children, the result will be empty. For more details, please visit my another virtual dom project amber-dom.

Here are a few projects or blogs this algorithm refered to:

Paramters

diff(source, target, key)

  • source {Array}: an array of object with some key.
  • targte {Array}: an array of updated object with some key.
  • key {String|Function}: the identifier of an object. If it is a function, each object is passed to it and it must return a string.
  • return {Object}: an object containing moves & a simulation object diffed.

Example

Consider a group of prisoners just got escaped from jail, and they changed their names. It doesn't matter, though, because we have clues. Assume we can find them by their keys.

after being diffed, the prisoners will be found in .diffed, and .moves tells us how to find them from the group of people step by step

  • remove(free those innocent),
  • insert(find this prisoner somewhere else),
  • or move(adjust their positions)).
import diff from 'linear-list-diff';
 
 
const people = [{key: 'a', name: 'Mary'},
                {key: 'b', name: 'John'},
                {key: 'f', name: 'Kelly'},
                {key: 'c', name: 'Jim'},
                {key: 'e', name: 'Alien'}];
 
const prisoners = [{key: 'a', name: 'Stan'},
                {key: 'e', name: 'Nicholas'},
                {key: 'c', name: 'Sasha'},
                {key: 'f', name: 'Another one'}];
 
// Normal case.
const diffs = diff(prisoners, people, 'key'); 
console.log(diffs.moves)   //=> [ { type: 'INSERT', index: 1, item: { key: 'b', name: 'John' } },
                           // { type: 'MOVE', from: 4, to: 2 },
                           // { type: 'MOVE', from: 4, to: 3 } ]
 
console.log(diffs.diffed)  //=> [ { key: 'a', name: 'Stan' },
                           // { key: 'b', name: 'John' },
                           // { key: 'f', name: 'Another one' },
                           // { key: 'c', name: 'Sasha' },
                           // { key: 'e', name: 'Nicholas' } ]

But if we have no clues on them, we can't find them:

const diffs = diff(prisoners, people, 'no clues'); // => { moves: [], diffed: prisoners }

Usage

First install it via npm or download it directly:

npm i linear-list-diff
 
## or 
 
git clone https://github.com/Alieeeeen/linear-list-diff.git
  • To run test in Node.js:
npm run build && npm run test
  • To use CommonJS:
const diff = require('linear-list-diff/dist');
  • To run in browser, just include dist/list-diff.js:
<script src="path/to/dist/list-diff.js"></script>
<script>
    var moves = diff([{id: 1}, {id: 2}], [{id: 1}], 'id');
</script> 

To run in Node, simply require('linear-list-diff')

Readme

Keywords

Package Sidebar

Install

npm i linear-list-diff

Weekly Downloads

1

Version

1.0.2

License

ISC

Unpacked Size

13.7 kB

Total Files

8

Last publish

Collaborators

  • alieeeeen