Difference
Simple way to identify what is different between 2 instances of any type. Must have for TDD.
Top Related Projects
Diff Match Patch is a high-performance library in multiple languages that manipulates plain text.
A javascript text differencing implementation.
Diff & patch JavaScript objects
Pretty diff to html javascript library (diff2html)
Quick Overview
Difference is a Swift library that provides a lightweight way to identify differences between collections. It's designed to be efficient and easy to use, making it ideal for tasks like updating table or collection views in iOS applications.
Pros
- Fast and efficient algorithm for finding differences
- Simple API that's easy to integrate into existing projects
- Supports custom equality comparisons for complex objects
- Works with any collection type conforming to
BidirectionalCollection
Cons
- Limited to Swift projects, not available for other languages
- May require additional setup for complex data structures
- Documentation could be more extensive for advanced use cases
Code Examples
Comparing two arrays of integers:
let old = [1, 2, 3, 4, 5]
let new = [1, 3, 4, 5, 6]
let diff = old.difference(from: new)
print(diff) // Prints the difference between the two arrays
Using custom equality comparison for structs:
struct Person: Equatable {
let id: Int
let name: String
}
let oldPeople = [Person(id: 1, name: "Alice"), Person(id: 2, name: "Bob")]
let newPeople = [Person(id: 1, name: "Alice"), Person(id: 3, name: "Charlie")]
let diff = oldPeople.difference(from: newPeople) { $0.id == $1.id }
Applying changes to a collection:
var collection = [1, 2, 3, 4, 5]
let changes = collection.difference(from: [1, 3, 4, 5, 6])
collection.apply(changes)
print(collection) // Prints [1, 3, 4, 5, 6]
Getting Started
- Add Difference to your project using Swift Package Manager:
dependencies: [
.package(url: "https://github.com/krzysztofzablocki/Difference.git", from: "1.0.0")
]
- Import Difference in your Swift file:
import Difference
- Use the
difference(from:)
method on collections to find differences:
let oldArray = [1, 2, 3]
let newArray = [2, 3, 4]
let diff = oldArray.difference(from: newArray)
Competitor Comparisons
Diff Match Patch is a high-performance library in multiple languages that manipulates plain text.
Pros of diff-match-patch
- Multi-language support (C++, Java, JavaScript, Dart, Python, Lua)
- Robust algorithm for handling complex text differences
- Well-documented and maintained by Google
Cons of diff-match-patch
- More complex implementation, potentially overkill for simple use cases
- Not specifically optimized for Swift or iOS development
- Larger codebase and potential overhead
Code Comparison
diff-match-patch:
dmp = diff_match_patch()
patches = dmp.patch_make(text1, text2)
result = dmp.patch_apply(patches, text1)
Difference:
let diff = Difference.diff(between: text1, and: text2)
let applied = Difference.apply(diff, to: text1)
Summary
diff-match-patch offers a comprehensive, multi-language solution for text differencing and patching, making it suitable for various platforms and complex scenarios. However, it may be overly complex for simpler use cases, especially in Swift-based iOS development.
Difference, on the other hand, provides a more streamlined and Swift-specific implementation, which can be advantageous for iOS developers looking for a lightweight and easy-to-integrate solution. It may lack some advanced features of diff-match-patch but offers simplicity and native Swift support.
The choice between the two depends on the specific requirements of the project, target platform, and desired level of complexity.
A javascript text differencing implementation.
Pros of jsdiff
- Language-agnostic: Works with various programming languages and text formats
- Extensive API: Offers multiple diffing algorithms and output formats
- Well-established: Mature project with a large user base and active maintenance
Cons of jsdiff
- Performance: May be slower for large datasets compared to Difference
- Language-specific features: Lacks specialized support for Swift-specific syntax
Code Comparison
Difference (Swift):
let diff = Difference.diff(between: oldString, and: newString)
for change in diff {
switch change {
case .insert(let string): print("Inserted: \(string)")
case .delete(let string): print("Deleted: \(string)")
}
}
jsdiff (JavaScript):
const diff = Diff.diffChars(oldString, newString);
diff.forEach((part) => {
const color = part.added ? 'green' : part.removed ? 'red' : 'grey';
console.log(`%c${part.value}`, `color: ${color}`);
});
Summary
Difference is tailored for Swift development, offering specialized features for iOS and macOS projects. jsdiff, on the other hand, provides a more versatile solution for various programming languages and text formats. While jsdiff offers greater flexibility, Difference may provide better performance and integration for Swift-specific use cases.
Diff & patch JavaScript objects
Pros of jsondiffpatch
- Language-agnostic: Works with JSON data, making it usable across various programming languages
- Extensive features: Supports array diffing, custom equality checks, and formatters
- Web-ready: Includes browser-compatible versions and visual diff components
Cons of jsondiffpatch
- Limited to JSON: Not designed for diffing other data types or structures
- Performance: May be slower for large datasets compared to language-specific solutions
- Complexity: More complex API and setup process for advanced features
Code Comparison
jsondiffpatch:
var jsondiffpatch = require('jsondiffpatch');
var delta = jsondiffpatch.diff(obj1, obj2);
jsondiffpatch.patch(obj1, delta);
Difference:
let diff = Difference.diff(old: oldArray, new: newArray)
let applied = Difference.apply(diff: diff, to: oldArray)
Summary
jsondiffpatch is a versatile JSON diffing tool with broad language support and extensive features, but it's limited to JSON data and may have performance trade-offs. Difference, on the other hand, is a Swift-specific solution that offers simplicity and potentially better performance for Swift applications, but lacks the cross-language compatibility of jsondiffpatch.
Pretty diff to html javascript library (diff2html)
Pros of diff2html
- Web-based solution, making it easily accessible across platforms
- Supports multiple programming languages and file formats
- Offers both client-side and server-side rendering options
Cons of diff2html
- Requires JavaScript to function, which may not be ideal for all use cases
- Less integrated with native iOS development workflows
- May have higher overhead for simple diff comparisons
Code Comparison
diff2html (JavaScript):
var diff2html = require('diff2html').Diff2Html;
var diffJson = diff2html.parse(diffString);
var diffHtml = diff2html.html(diffJson, {
drawFileList: true,
matching: 'lines'
});
Difference (Swift):
let diff = Difference.diff(between: oldString, and: newString)
let attributedDiff = diff.convertToAttributedStrings(
deleteColor: .red,
insertColor: .green,
equalColor: .black
)
diff2html is a versatile web-based solution for rendering diffs, while Difference is a Swift library specifically designed for iOS development. diff2html offers broader language support and platform flexibility, but Difference provides tighter integration with iOS apps and potentially better performance for native applications.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Difference
Better way to identify what's different between 2 instances.
Have you ever written tests?
Usually they use equality asserts, e.g. XCTAssertEqual
, what happens if the objects aren't equal? Xcode throws a wall of text at you:
This forces you to manually scan the text and try to figure out exactly what's wrong, what if instead you could just learn which property is different?
Installation
CocoaPods
Add pod 'Difference'
to your Podfile.
Carthage
Add github "krzysztofzablocki/Difference"
to your Cartfile.
SwiftPM
Add .package(url: "https://github.com/krzysztofzablocki/Difference.git", branch: "master")
dependency in your Package manifest.
Using lldb
Write the following to see the difference between 2 instances:
po dumpDiff(expected, received)
Integrate with XCTest
Add this to your test target:
public func XCTAssertEqual<T: Equatable>(_ expected: @autoclosure () throws -> T, _ received: @autoclosure () throws -> T, file: StaticString = #filePath, line: UInt = #line) {
do {
let expected = try expected()
let received = try received()
XCTAssertTrue(expected == received, "Found difference for \n" + diff(expected, received).joined(separator: ", "), file: file, line: line)
}
catch {
XCTFail("Caught error while testing: \(error)", file: file, line: line)
}
}
Replace #filePath
with #file
if you're using Xcode 11 or earlier.
Integrate with Quick
Add this to your test target:
public func equalDiff<T: Equatable>(_ expectedValue: T?) -> Predicate<T> {
return Predicate.define { actualExpression in
let receivedValue = try actualExpression.evaluate()
if receivedValue == nil {
var message = ExpectationMessage.fail("")
if let expectedValue = expectedValue {
message = ExpectationMessage.expectedCustomValueTo("equal <\(expectedValue)>", actual: "nil")
}
return PredicateResult(status: .fail, message: message)
}
if expectedValue == nil {
return PredicateResult(status: .fail, message: ExpectationMessage.fail("").appendedBeNilHint())
}
return PredicateResult(bool: receivedValue == expectedValue, message: ExpectationMessage.fail("Found difference for " + diff(expectedValue, receivedValue).joined(separator: ", ")))
}
}
Write the following to see the difference between 2 instances:
expect(received).to(equalDiff(expected))
Integrate with The Composable Architecture
If you are using The Composable Architecture nameLabels
configuration to get a diff that's more appropiate for reducer instrumentation
diff(oldState, newState, indentationType: .pipe, nameLabels: .comparing)
You can use this function in your own variant of ReducerInstrumentation code based on this
That way your diffs will look more like this:
Received action:
AppAction.home(.howTo(.setSelectedSlide))
State:
home:
| selectedHowTo:
| | selectedSlide:
| | | Current: 8mnkni91h4fe
| | | Previous: exei4wpqsmdk
Top Related Projects
Diff Match Patch is a high-performance library in multiple languages that manipulates plain text.
A javascript text differencing implementation.
Diff & patch JavaScript objects
Pretty diff to html javascript library (diff2html)
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot