Last active
December 8, 2023 18:11
-
-
Save Maksimka101/f300dccf2589070faffddbb9fd227c95 to your computer and use it in GitHub Desktop.
Fast Equatable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
abstract class FastEquatable extends Equatable { | |
const FastEquatable(); | |
@override | |
bool operator ==(Object other) { | |
return identical(this, other) || | |
other is FastEquatable && | |
other.runtimeType == runtimeType && | |
fastEquals(props, other.props); | |
} | |
} | |
bool fastEquals(List? list1, List? list2) { | |
if (identical(list1, list2)) return true; | |
if (list1 == null || list2 == null) return false; | |
final length = list1.length; | |
if (length != list2.length) return false; | |
for (var i = 0; i < length; i++) { | |
if (!_objectsEquals(list1[i], list2[i])) return false; | |
} | |
return true; | |
} | |
bool _objectsEquals(Object? object1, Object? object2) { | |
if (identical(object1, object2)) { | |
return true; | |
} else if (_isEquatable(object1) && _isEquatable(object2)) { | |
if (object1 != object2) return false; | |
} else if (object1 is List && object2 is List) { | |
return _fastEqualsIterable(object1, object2); | |
} else if (object1 is Set && object2 is Set) { | |
return _fastEqualsSet(object1, object2); | |
} else if (object1 is Map && object2 is Map) { | |
return _fastEqualsMap(object1, object2); | |
} else if (object1?.runtimeType != object2?.runtimeType) { | |
return false; | |
} else if (object1 != object2) { | |
return false; | |
} | |
return true; | |
} | |
bool _isEquatable(Object? object) { | |
return object is FastEquatable || | |
object is FastEquatableMixin || | |
object is Equatable || | |
object is EquatableMixin; | |
} | |
bool _fastEqualsSet(Set a, Set b) { | |
final aLength = a.length; | |
if (aLength != b.length) return false; | |
if (identical(a, b)) return true; | |
for (final element in a) { | |
if (!b.contains(element)) return false; | |
} | |
return true; | |
} | |
bool _fastEqualsIterable(Iterable a, Iterable b) { | |
final aLength = a.length; | |
if (aLength != b.length) return false; | |
if (identical(a, b)) return true; | |
for (var i = 0; i < aLength; i++) { | |
if (!_objectsEquals(a.elementAt(i), b.elementAt(i))) return false; | |
} | |
return true; | |
} | |
bool _fastEqualsMap(Map a, Map b) { | |
final aLength = a.length; | |
if (aLength != b.length) return false; | |
if (identical(a, b)) return true; | |
for (final key in a.keys) { | |
if (!_objectsEquals(a[key], b[key])) return false; | |
} | |
return true; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment