Skip to content

Instantly share code, notes, and snippets.

@Maksimka101
Last active December 8, 2023 18:11
Show Gist options
  • Save Maksimka101/f300dccf2589070faffddbb9fd227c95 to your computer and use it in GitHub Desktop.
Save Maksimka101/f300dccf2589070faffddbb9fd227c95 to your computer and use it in GitHub Desktop.
Fast Equatable
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