Skip to content

Commit

Permalink
Add difference to ListExtensions
Browse files Browse the repository at this point in the history
  • Loading branch information
ebraminio committed Aug 15, 2023
1 parent 1ed009e commit 89b7f41
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## 1.19.0-wip

- Adds `subtract` to `ListExtensions`.
- Adds `shuffled` to `IterableExtension`.
- Shuffle `IterableExtension.sample` results.

Expand Down
24 changes: 24 additions & 0 deletions lib/src/list_extensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import 'dart:math';
import 'algorithms.dart';
import 'algorithms.dart' as algorithms;
import 'equality.dart';
import 'iterable_extensions.dart';
import 'utils.dart';

/// Various extensions on lists of arbitrary elements.
Expand Down Expand Up @@ -286,6 +287,29 @@ extension ListExtensions<E> on List<E> {
yield slice(i, min(i + length, this.length));
}
}

/// Returns a new list with the elements of [other] are removed from `this`.
///
/// It's aware about occurrence count and removes things only the amount
/// they are present in [other].
Iterable<E> subtract(List<E> other) sync* {
var elementsCount = other.groupFoldBy<E, int>(
(e) => e,
(previous, element) => (previous ?? 0) + 1,
);
for (final element in this) {
var count = elementsCount[element];
if (count == null) {
yield element;
} else {
if (count == 1) {
elementsCount.remove(element);
} else {
elementsCount[element] = count - 1;
}
}
}
}
}

/// Various extensions on lists of comparable elements.
Expand Down
17 changes: 17 additions & 0 deletions test/extensions_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1953,6 +1953,23 @@ void main() {
expect(list, [9, 8, 5, 6, 3, 2, 4, 7, 1]);
});
});
group('.subtract', () {
test('empty', () {
expect(<int>[].subtract([]), []);
});
test('returns the element minuend shares nothing with the list', () {
expect([1, 2, 3, 4].subtract([5]), [1, 2, 3, 4]);
});
test('removes two element', () {
expect([1, 2, 3, 4].subtract([2, 3]), [1, 4]);
});
test('removes only one of the occurrence', () {
expect([1, 2, 2, 3].subtract([2]), [1, 2, 3]);
});
test('removes only two of the occurrences', () {
expect([1, 2, 2, 3].subtract([2, 0, 2]), [1, 3]);
});
});
});
}

Expand Down

0 comments on commit 89b7f41

Please sign in to comment.