Skip to content

Commit

Permalink
Add EqualityMap and EqualitySet. (dart-archive/collection#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
nex3 authored Nov 1, 2016
1 parent 054ac3f commit 9d3e0e1
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 1 deletion.
5 changes: 5 additions & 0 deletions pkgs/collection/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 1.11.0

* Add `EqualityMap` and `EqualitySet` classes which use `Equality` objects for
key and element equality, respectively.

## 1.10.1

* `Set.difference` now takes a `Set<Object>` as argument.
Expand Down
2 changes: 2 additions & 0 deletions pkgs/collection/lib/collection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export "src/algorithms.dart";
export "src/canonicalized_map.dart";
export "src/comparators.dart";
export "src/equality.dart";
export "src/equality_map.dart";
export "src/equality_set.dart";
export "src/functions.dart";
export "src/iterable_zip.dart";
export "src/priority_queue.dart";
Expand Down
32 changes: 32 additions & 0 deletions pkgs/collection/lib/src/equality_map.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:collection';

import 'equality.dart';
import 'wrappers.dart';

/// A [Map] whose key equality is determined by an [Equality] object.
class EqualityMap<K, V> extends DelegatingMap<K, V> {
/// Creates a map with equality based on [equality].
EqualityMap(Equality<K> equality)
: super(new LinkedHashMap(
equals: equality.equals,
hashCode: equality.hash,
isValidKey: equality.isValidKey));

/// Creates a map with equality based on [equality] that contains all
/// key-value pairs of [other].
///
/// If [other] has multiple keys that are equivalent according to [equality],
/// the last one reached during iteration takes precedence.
EqualityMap.from(Equality<K> equality, Map<K, V> other)
: super(new LinkedHashMap(
equals: equality.equals,
hashCode: equality.hash,
isValidKey: equality.isValidKey)) {
addAll(other);
}
}

32 changes: 32 additions & 0 deletions pkgs/collection/lib/src/equality_set.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:collection';

import 'equality.dart';
import 'wrappers.dart';

/// A [Map] whose key equality is determined by an [Equality] object.
class EqualitySet<E> extends DelegatingSet<E> {
/// Creates a set with equality based on [equality].
EqualitySet(Equality<E> equality)
: super(new LinkedHashSet(
equals: equality.equals,
hashCode: equality.hash,
isValidKey: equality.isValidKey));

/// Creates a set with equality based on [equality] that contains all
/// elements in [other].
///
/// If [other] has multiple values that are equivalent according to
/// [equality], the first one reached during iteration takes precedence.
EqualitySet.from(Equality<E> equality, Iterable<E> other)
: super(new LinkedHashSet(
equals: equality.equals,
hashCode: equality.hash,
isValidKey: equality.isValidKey)) {
addAll(other);
}
}

2 changes: 1 addition & 1 deletion pkgs/collection/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: collection
version: 1.10.1
version: 1.11.0
author: Dart Team <misc@dartlang.org>
description: Collections and utilities functions and classes related to collections.
homepage: https://www.github.com/dart-lang/collection
Expand Down
37 changes: 37 additions & 0 deletions pkgs/collection/test/equality_map_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:collection/collection.dart';
import 'package:test/test.dart';

void main() {
test("uses the given equality", () {
var map = new EqualityMap(const IterableEquality());
expect(map, isEmpty);

map[[1, 2, 3]] = 1;
expect(map, containsPair([1, 2, 3], 1));

map[[1, 2, 3]] = 2;
expect(map, containsPair([1, 2, 3], 2));

map[[2, 3, 4]] = 3;
expect(map, containsPair([1, 2, 3], 2));
expect(map, containsPair([2, 3, 4], 3));
});

test("EqualityMap.from() prefers the lattermost equivalent key", () {
var map = new EqualityMap.from(const IterableEquality(), {
[1, 2, 3]: 1,
[2, 3, 4]: 2,
[1, 2, 3]: 3,
[2, 3, 4]: 4,
[1, 2, 3]: 5,
[1, 2, 3]: 6,
});

expect(map, containsPair([1, 2, 3], 6));
expect(map, containsPair([2, 3, 4], 4));
});
}
48 changes: 48 additions & 0 deletions pkgs/collection/test/equality_set_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:collection/collection.dart';
import 'package:test/test.dart';

void main() {
test("uses the given equality", () {
var set = new EqualitySet(const IterableEquality());
expect(set, isEmpty);

var list1 = [1, 2, 3];
expect(set.add(list1), isTrue);
expect(set, contains([1, 2, 3]));
expect(set, contains(same(list1)));

var list2 = [1, 2, 3];
expect(set.add(list2), isFalse);
expect(set, contains([1, 2, 3]));
expect(set, contains(same(list1)));
expect(set, isNot(contains(same(list2))));

var list3 = [2, 3, 4];
expect(set.add(list3), isTrue);
expect(set, contains(same(list1)));
expect(set, contains(same(list3)));
});

test("EqualitySet.from() prefers the lattermost equivalent value", () {
var list1 = [1, 2, 3];
var list2 = [2, 3, 4];
var list3 = [1, 2, 3];
var list4 = [2, 3, 4];
var list5 = [1, 2, 3];
var list6 = [1, 2, 3];

var set = new EqualitySet.from(const IterableEquality(),
[list1, list2, list3, list4, list5, list6]);

expect(set, contains(same(list1)));
expect(set, contains(same(list2)));
expect(set, isNot(contains(same(list3))));
expect(set, isNot(contains(same(list4))));
expect(set, isNot(contains(same(list5))));
expect(set, isNot(contains(same(list6))));
});
}

0 comments on commit 9d3e0e1

Please sign in to comment.