Giter Club home page Giter Club logo

changeset's Introduction

Changeset

Changeset – pretty awesome little project
Joel Levin

This is an attempt at implementing the solution outlined in Dave DeLong’s article, Edit distance and edit steps.

A Changeset describes the minimal edits required to go from one Collection of Equatable elements to another.

It has been written primarily to be used in conjunction with UITableView and UICollectionView data sources by detecting additions, deletions, substitutions, and moves between the two sets of data. But it can also be used to compute more general changes between two data sets.

Usage

The following code computes the minimal edits of the canonical example, going from the String collections “kitten” to “sitting”:

let changeset = Changeset(source: "kitten", target: "sitting")

print(changeset)
// 'kitten' -> 'sitting':
//     replace with s at offset 0
//     replace with i at offset 4
//     insert g at offset 6

The following assertion would then succeed:

let edits = [
    Changeset<String>.Edit(operation: .substitution, value: "s", destination: 0),
    Changeset<String>.Edit(operation: .substitution, value: "i", destination: 4),
    Changeset<String>.Edit(operation: .insertion, value: "g", destination: 6),
]
assert(changeset.edits == edits)

If you don’t want the overhead of Changeset itself, which also stores the source and target collections, you can call edits directly (here with example data from Apple’s Table View Programming Guide for iOS):

let source = ["Arizona", "California", "Delaware", "New Jersey", "Washington"]
let target = ["Alaska", "Arizona", "California", "Georgia", "New Jersey", "Virginia"]
let edits = Changeset.edits(from: source, to: target)

print(edits)
// [insert Alaska at offset 0, replace with Georgia at offset 2, replace with Virginia at offset 4]

Note that Changeset uses offsets, not indices, to refer to elements in the collections. This is mainly because Swift collections aren’t guaranteed to use zero-based integer indices. See discussion in issue #37 for more details.

UIKit Integration

The offset values can be used directly in the animation blocks of beginUpdates/endUpdates on UITableView and performBatchUpdates on UICollectionView in that Changeset follows the principles explained under Batch Insertion, Deletion, and Reloading of Rows and Sections in Apple’s guide.

In short; first all deletions and substitutions are made, relative to the source collection, then, relative to the resulting collection, insertions. A move is just a deletion followed by an insertion.

In the iOS framework, two convenience extensions (one on UITableView and one on UICollectionView) have been included to make animated table/collection view updates a breeze. Just call update, like this:

tableView.update(with: changeset.edits)

Custom Comparator

By default a Changeset uses == to compare elements, but you can write your own comparator, illustrated below, where the occurence of an “a” always triggers a change:

let alwaysChangeA: (Character, Character) -> Bool = {
    if $0 == "a" || $1 == "a" {
        return false
    } else {
        return $0 == $1
    }
}
let changeset = Changeset(source: "ab", target: "ab", comparator: alwaysChangeA)

As a result, the changeset will consist of a substitution of the “a” (to another “a”):

let expectedEdits: [Changeset<String>.Edit] = [Changeset.Edit(operation: .substitution, value: "a", destination: 0)]
assert(changeset.edits == expectedEdits)

One possible use of this is when a cell in a UITableView or UICollectionView shouldn’t animate when they change.

Test App

The Xcode project also contains a target to illustrate the usage in an app:

Test App

This uses the extensions mentioned above to animate transitions based on the edits of a Changeset.

License

This project is available under The MIT License.
Copyright © 2015-18, Joachim Bondo. See LICENSE file.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.