collection
collection copied to clipboard
Equality subclass which is conjunction of other Equalities
Currently I do something like:
bool operator ==(other) =>
other is TaskInvocation &&
name == other.name &&
const IterableEquality().equals(positionals, other.positionals) &&
const MapEquality().equals(options, other.options);
int get hashCode =>
name == other.name.hashCode ^
(const IterableEquality().hash(positionals) * 3) ^
(const MapEquality().hash(options) * 5);
which has lots of duplication between ==
and hashCode
. I'd prefer to have something like:
class AndEquality<E> {
/// Equality for which elements are equal if equal according to all in [equalities].
const AndEquality<E>(Iterable<Equality<E>> equalities);
}
Why not use hashCode in your == definition?
bool operator ==(other) =>
other is TaskInvocation && hashCode == other.hashCode;
int get hashCode =>
name.hashCode ^
(const IterableEquality().hash(positionals) * 3) ^
(const MapEquality().hash(options) * 5);
@kharland hashCode
is required to be equal for instances that are considered equal, but hashCode
is not required to be different for instances that are considered not equal
This has been open since 2015 without action so I am closing as stale.
Re-opening as per https://github.com/dart-lang/collection/issues/6#issuecomment-372500079.
Basically, what is needed is a way to create an equality for a type by extracting properties from the type and assigning an equality to each.
Either operation might be useful by itself, so:
class PropertyEquality<T, S> implements Equality<T>{
final S Function(T) _propertyValue;
final Equality<S> propertyEquality;
PropertyEquality(S Function(T) propertyValue, this.propertyEquality): _propertyValue = propertyValue;
S propertyValue(T object) => _propertyValue(object);
bool equals(T object1, T object2) =>
propertyEquality.equals(_propertyValue(object1), _propertyValue(object2));
int hash(T object) => propertyEquality.hash(_propertyValue(object));
bool isValidKey(Object object) => object is T;
}
class CompositeEquality<T> implements Equality<T> {
final List<Equality<T>> _equalities;
CompositeEquality(Iterable<Equality<T>> equalities) : _equalities = [...equalities];
bool equals(T object1, T object2) {
for (var eq in _equalities) if (!eq.equals(object1, object2)) return false;
return true;
}
int hash(T object) {
int hash = 0;
for (var eq in _equalities) {
// Or some other way to combine hashes.
hash = hash * 37;
hash ^= eq.hash(object)
hash &= 0x3FFFFFFF;
}
return hash;
}
bool isValidKey(Object object) => object is T;
}