{"id":27938543,"url":"https://github.com/willowtreeapps/tablediff","last_synced_at":"2025-05-07T08:49:11.025Z","repository":{"id":56923605,"uuid":"62076140","full_name":"willowtreeapps/tablediff","owner":"willowtreeapps","description":null,"archived":false,"fork":false,"pushed_at":"2019-07-24T21:19:12.000Z","size":17125,"stargazers_count":11,"open_issues_count":4,"forks_count":4,"subscribers_count":27,"default_branch":"develop","last_synced_at":"2025-04-11T06:19:23.460Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/willowtreeapps.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-06-27T17:53:26.000Z","updated_at":"2022-03-09T02:36:35.000Z","dependencies_parsed_at":"2022-08-21T05:20:35.700Z","dependency_job_id":null,"html_url":"https://github.com/willowtreeapps/tablediff","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willowtreeapps%2Ftablediff","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willowtreeapps%2Ftablediff/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willowtreeapps%2Ftablediff/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willowtreeapps%2Ftablediff/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/willowtreeapps","download_url":"https://codeload.github.com/willowtreeapps/tablediff/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252847236,"owners_count":21813438,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-05-07T08:49:10.386Z","updated_at":"2025-05-07T08:49:11.006Z","avatar_url":"https://github.com/willowtreeapps.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TableDiff\n\nTableDiff is a small library that takes two collections and generates\na diff that is suitable for feeding into `UITableView` or\n`UICollectionView` to animate the changes. It additionally tracks\nwhich items have been updated so that UI code can adjust individual\nrows or cells.\n\nWe created it to animate between distinct collection states in a Redux-like\narchitecture like [ReSwift](https://github.com/ReSwift/ReSwift).\n\n### Table of Contents\n\n* [Getting Started](#getting-started)\n* [Implementations](#implementations)\n* [Updates](#updates)\n* [Goals and Non-Goals](#goals)\n* [Bugs and Feature Requests](#bugs)\n* [Contributing](#contributing)\n\n## Getting Started\u003ca name=\"getting-started\"\u003e\u003c/a\u003e\n\nPlease see the [demo](https://github.com/willowtreeapps/TableDiff/tree/develop/Demo)\napp for a working example.\n\nInitially you will want to make the elements in your datasource to conform to\nthe protocol `SequenceDiffable`. This means you need to\n* Conform to `Equatable`\n* Have a `identifier` variable that is `Hashable`\n\nThe `identifier` is used to determine if two items are the same, while equality\nchecks to see if the same item has been updated.\n\nWhen you want to update the datasource you will need to calculate the diff:\n\n```swift\nlet (diff, updates) = originalData.tableDiff(newData)\n```\n\nThen you can choose to either perform all the updates yourself or you can use the\nconvenience extensions to handle the moves/inserts/deletes:\n\n```swift\ntableView.applyDiff(diff)\ncollectionView.applyDiff(diff)\n```\n\nUpdates still need to be managed manually, as this is app specific code. You\ncan change the animation styles with additional parameters on the helpers.\n\n### Implementations\u003ca name=\"implementations\"\u003e\u003c/a\u003e\n\nWe originally approached this problem with a\n[Longest Common Subsequence](https://en.wikipedia.org/wiki/Longest_common_subsequence_problem)\nalgorithm, based on the work of [Dwifft](https://github.com/jflinter/Dwifft).\nHowever, that algorithm only speaks in inserts and deletes, while for some use\ncases we would prefer to use `UITableView`'s move capabilities.\n\nWe provide three different implementation options:\n\n* `.lcs`: This is the original LCS based algorithm, which only returns inserts\n  and deletes.\n* `.lcsWithMoves`: This is the same algorithm with a post-processing step included\n  to turn some delete/insert pairs into moves. This does not always line up with\n  what you may perceive as the \"intuitive moves\".\n* `.allMoves`: This algorithm looks for all possible moves first, and then layers\n  in inserts and deletes. It creates the nicest effect for moves, but has more\n  extraneous instructions in the diff.\n\nYou can choose which implementation to use via a parameter. The default value is\n`.allMoves`.\n\n```swift\ntableView.applyDiff(diff, implementation: .lcs)\n```\n\n### Updates\u003ca name=\"updates\"\u003e\u003c/a\u003e\n\nUpdates to an individual item are tracked while the diff is created. But since\nan update implies the same item is in both collections, you have the choice of\nwhich collection's indices you'd like to use. You can choose to have the first\ncollection's indices with `.pre`, or the second collection's with `.post`. The\ndefault is `.pre`.\n\n```swift\ntableView.applyDiff(diff, updateStyle: .post)\n```\n\n## Goals\u003ca name=\"goals\"\u003e\u003c/a\u003e\n\n* Calculate diff between 2 `CollectionTypes` :+1:\n* Translate diff into moves/inserts/deletes/updates :+1:\n* Adapt algorithm to be used with sections\n\n## Bugs and Feature Requests\u003ca name=\"bugs\"\u003e\u003c/a\u003e\n\nHave a bug or a feature request? Please first read the\n[issue guidelines](https://github.com/willowtreeapps/tablediff/blob/develop/CONTRIBUTING.md)\nand search for existing and closed issues. If your problem or idea is not\naddressed yet, please open a\n [new issue](https://github.com/willowtreeapps/TableDiff/issues/new).\n\n## Contributing\u003ca name=\"contributing\"\u003e\u003c/a\u003e\n\nPlease read through our\n[contributing guidelines](https://github.com/willowtreeapps/tablediff/blob/develop/CONTRIBUTING.md).\nIncluded are directions for opening issues, coding standards, and notes on development.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillowtreeapps%2Ftablediff","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwillowtreeapps%2Ftablediff","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillowtreeapps%2Ftablediff/lists"}