diff --git a/example/immutables_example.dart b/example/immutables_example.dart deleted file mode 100644 index f0c2900..0000000 --- a/example/immutables_example.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:immutables/immutables.dart'; - -main() { - var c = IList([1, 2, 3]); - - print((c + 4).value); // [1, 2, 3, 4] - print(c.value); // [1, 2, 3] - - print((c - 3).value); // [1, 2] - print(c.value); // [1, 2, 3] - - print(c.take(2).value); // [1, 2] - print(c.value); // [1, 2] - - print(c.filter((_) => 1 == _ || 2 == _).value); // [1, 2] - print(c.value); // [1, 2, 3] -} diff --git a/lib/src/list.dart b/lib/src/list.dart index 99baf73..41bfd95 100644 --- a/lib/src/list.dart +++ b/lib/src/list.dart @@ -1,147 +1,77 @@ +import 'dart:math'; + class IList { - List _value; - - List get value => _toList(); - - int get length => _value.length; - - E get first => _value.first; - - E get last => _value.last; - - E get head => first; - - IList get tail => skip(1); - - bool get isEmpty => _value.isEmpty; - - IList(value) { - if (value is List) - _value = value; - else - this._value = List.from(value); - } - - bool contains(E _) => _value.contains(_); - - E reduce(E f(E, E _)) => _value.reduce(f); - - T fold(T _, T f(T, E)) => _value.fold(_, f); - - /** - * The same with List.map() - * - * IList([1, 2, 3]).map((value) => value + 1).value; // [2, 3, 4] - * - */ - IList map(T f(E)) => fold(IList([]), (acc, _) => acc.add(f(_))); - - /** - * - * IList([1]).take(-1).value; // [1] - * IList([1]).take(0).value; // [1] - * IList([1, 2, 3]).take(2).value; // [1, 2] - * - */ - IList take(int length) => - 0 >= length ? IList(_value.take(1)) : IList(_value.take(length)); - - /** - * - * IList([1]).skip(-1).value; // [1] - * IList([1]).skip(0).value; // [1] - * IList([1, 2, 3]).skip(2).value; // [3] - * - */ - IList skip(int length) => - 0 > length ? IList(_value.skip(0)) : IList(_value.skip(length)); - - /** - * - * IList([2, 4, 6, 8]).firstWhere((value) => 0 == (value % 2)); // 2 - * - */ - /* E | null */ firstWhere(bool f(E)) => _oneWhere(_value, f); - - /** - * - * IList([2, 4, 6, 8]).lastWhere((value) => 0 == (value % 2)); // 8 - * - */ - /* E | null */ lastWhere(bool f(E)) => _oneWhere(_value.reversed.toList(), f); - - /** - * - * IList([1, 2, 3, 4, 5]).removeWhere((value) => 0 == (value % 2)).value; // [1, 3, 5] - * - */ - IList removeWhere(bool f(E)) => IList(_toList()..removeWhere((_) => f(_))); - - /** - * - * IList([1, 2, 3, 4, 5]).removeWhere((value) => 0 == (value % 2)).value; // [1, 3, 5] - * - */ - IList filter(bool f(E)) => removeWhere((_) => !f(_)); - - /** - * - * IList([1, 2, 3]).addAll([4, 5]).value; // 1, 2, 3, 4, 5 - * - */ - IList addAll(List _) => IList([]..addAll(_value)..addAll(_)); - - /** - * - * IList([1, 2]).add(3).value; // [1, 2, 3] - * - */ - IList add(_) => _ is List ? addAll(_) : IList(_toList()..add(_)); - - /** - * - * var a = IList([1, 2]) + 3; - * a.value; // [1, 2, 3] - * - * a = a + [4, 5]; - * a.value; // [1, 2, 3, 4, 5] - * - */ - IList operator +(_) => add(_); - - /** - * - * IList([1, 2, 3, 4, 5]).removeContains([1, 2, 5]).value; // [3, 4] - * - */ - IList removeContains(List _) => removeWhere((v) => _.contains(v)); - - /** - * - * IList([1, 2, 3]).remove(3).value; // [1, 2] - * - */ - IList remove(_) => - _ is List ? removeContains(_) : IList(_toList()..remove(_)); - - /** - * - * var a = IList([1, 2, 3, 4, 5]) - 3; - * a.value; // [1, 2, 4, 5] - * - * a = a - [4, 5]; - * a.value; // [1, 2] - * - */ - IList operator -(_) => remove(_); - - E operator [](int index) => _value[index]; - - void operator []=(int _, E value) => throw new Exception('Woops'); - - List _toList() => _value.toList(); - - /* E | null */ _oneWhere(List values, bool f(E _)) { - for (var _ in values) if (f(_)) return _; - } + final List _; + + get isEmpty => _.isEmpty; + + get isNotEmpty => _.isNotEmpty; + + IList([Iterable elements]) : _ = List.from(elements ?? []); + + IList.filled(int length, E fill) : _ = List.filled(length, fill); + + IList.generate(int length, E generator(int index)) + : _ = List.generate(length, generator); + + E operator [](int index) => _[index]; + + int get length => _.length; + + Iterable get reversed => _.reversed; + + IList sort([int compare(E a, E b)]) => IList(_).._.sort(compare); + + IList shuffle([Random random]) => IList(_).._.shuffle(random); + + int indexOf(E element, [int start = 0]) => _.indexOf(element, start); + + int indexWhere(bool test(E element), [int start = 0]) => + _.indexWhere(test, start); + + int lastIndexWhere(bool test(E element), [int start]) => + _.lastIndexWhere(test, start); + + int lastIndexOf(E element, [int start]) => _.lastIndexOf(element, start); + + IList insert(int index, E element) => IList(_).._.insert(index, element); + + IList insertAll(int index, Iterable iterable) => + IList(_).._.insertAll(index, iterable); + + IList setAll(int index, Iterable iterable) => + IList(_).._.setAll(index, iterable); + + IList remove(E element) => IList(_).._.remove(element); + + IList removeAt(int index) => IList(_).._.removeAt(index); + + IList removeLast() => IList(_).._.removeLast(); + + IList removeWhere(bool test(E element)) => IList(_).._.removeWhere(test); + + IList retainWhere(bool test(E element)) => IList(_).._.retainWhere(test); + + IList operator +(IList other) => IList(_ + other._); + + IList sublist(int start, [int end]) => IList(_.sublist(start, end)); + + Iterable getRange(int start, int end) => _.getRange(start, end); + + IList setRange(int start, int end, Iterable iterable, + [int skipCount = 0]) => + IList(_).._.setRange(start, end, iterable, skipCount); + + IList removeRange(int start, int end) => + IList(_).._.removeRange(start, end); + + IList fillRange(int start, int end, [E fillValue]) => + IList(_).._.fillRange(start, end, fillValue); + + IList replaceRange(int start, int end, Iterable replacement) => + IList(_).._.replaceRange(start, end, replacement); + + Map asMap() => _.asMap(); + + void forEach(void f(E element)) => _.forEach(f); } diff --git a/test/list_test.dart b/test/list_test.dart index 2c6a35c..1e27d39 100644 --- a/test/list_test.dart +++ b/test/list_test.dart @@ -2,247 +2,14 @@ import 'package:immutables/immutables.dart'; import 'package:test/test.dart'; void main() { - var a = IList([1]); - var b = IList(['q']); - var c = IList([1, 2, 3]); - var d = IList([ - {'a': 1}, - {'b': 2} - ]); - - test('Value getter', () { - a.value.add(22); - expect(a.value, [1]); - - c.tail.add(5).add(11); - expect(c.value, [1, 2, 3]); - }); - test('Getters', () { - expect(a.length, 1); - expect(b.length, 1); - expect(c.length, 3); - expect(d.length, 2); - - expect(a.first, 1); - expect(b.first, 'q'); - expect(c.first, 1); - expect(d.first, {'a': 1}); - - expect(a.last, 1); - expect(b.last, 'q'); - expect(c.last, 3); - expect(d.last, {'b': 2}); - - expect(a.isEmpty, false); - expect(b.isEmpty, false); - expect(c.isEmpty, false); - expect(d.isEmpty, false); - expect(IList([]).isEmpty, true); - }); - - test('Contains', () { - expect(a.contains(1), true); - expect(a.contains(2), false); - - expect(b.contains('e'), false); - expect(b.contains('q'), true); - - expect(c.contains(2), true); - expect(c.contains(3), true); - expect(c.contains(0), false); - }); - - test('reduce', () { - expect(a.reduce((acc, value) => value + 1), 1); - expect(b.reduce((acc, value) => value + 'w'), 'q'); - expect(c.reduce((acc, value) => acc + value), 6); - expect(d.reduce((acc, value) => {'b': 2}), {'b': 2}); - }); - - test('Fold', () { - expect(a.fold(1, (acc, value) => value + 1), 2); - expect(b.fold('w', (acc, value) => value + 'w'), 'qw'); - expect(c.fold(0, (acc, value) => acc + value), 6); - expect(d.fold({'c': 2}, (acc, value) => acc), {'c': 2}); - }); - - test('Map', () { - expect(a.map((_) => _ + 1).value, IList([2]).value); - expect(b.map((_) => _ + 'w').value, IList(['qw']).value); - expect( - c.map((_) => {'a': _}).value, - IList([ - {'a': 1}, - {'a': 2}, - {'a': 3} - ]).value); - }); - - test('take', () { - expect(a.take(-1).value, [1]); - expect(a.take(0).value, [1]); - expect(a.take(2).value, [1]); - - expect(b.take(-1).value, ['q']); - expect(b.take(0).value, ['q']); - expect(b.take(2).value, ['q']); - - expect(c.take(-1).value, [1]); - expect(c.take(0).value, [1]); - expect(c.take(2).value, [1, 2]); - expect(c.take(44444).value, [1, 2, 3]); - }); - - test('skip', () { - expect(a.skip(-1).value, [1]); - expect(a.skip(0).value, [1]); - expect(a.skip(2).value, []); - - expect(b.skip(-1).value, ['q']); - expect(b.skip(0).value, ['q']); - expect(b.skip(2).value, []); - - expect(c.skip(-1).value, [1, 2, 3]); - expect(c.skip(0).value, [1, 2, 3]); - expect(c.skip(2).value, [3]); - expect(c.skip(44444).value, []); - }); - - test('firstWhere', () { - expect(a.firstWhere((_) => _ == 2), null); - expect(a.firstWhere((_) => _ == 1), 1); - expect(a.value, [1]); - - expect(b.firstWhere((_) => _ == 'ww'), null); - expect(b.firstWhere((_) => _ == 'q'), 'q'); - expect(b.value, ['q']); - - expect(c.firstWhere((_) => _ == 2), 2); - expect(c.firstWhere((_) => _ == 1), 1); - expect(c.firstWhere((_) => _ == 0), null); - expect(c.value, [1, 2, 3]); - - expect(IList([2, 4, 6, 8]).firstWhere((_) => 0 == (_ % 2)), 2); + test('empty list is empty', () { + final empty = IList(); + expect(empty.isEmpty, true); + expect(empty.isNotEmpty, false); }); - test('lastWhere', () { - expect(a.lastWhere((_) => _ == 2), null); - expect(a.lastWhere((_) => _ == 1), 1); - expect(a.value, [1]); + test('can concat two lists', () { - expect(b.lastWhere((_) => _ == 'ww'), null); - expect(b.lastWhere((_) => _ == 'q'), 'q'); - expect(b.value, ['q']); - - expect(c.lastWhere((_) => _ == 2), 2); - expect(c.lastWhere((_) => _ == 1), 1); - expect(c.lastWhere((_) => _ == 0), null); - expect(c.value, [1, 2, 3]); - - expect(IList([2, 4, 6, 8]).lastWhere((_) => 0 == (_ % 2)), 8); - }); - - test('removeWhere', () { - expect(a.removeWhere((_) => _ == 1).value, []); - expect(a.removeWhere((_) => _ == 0).value, [1]); - expect(a.value, [1]); - - expect(b.removeWhere((_) => _ == 'q').value, []); - expect(b.removeWhere((_) => _ == 'w').value, ['q']); - expect(b.value, ['q']); - - expect(c.removeWhere((_) => _ == 1).value, [2, 3]); - expect(c.removeWhere((_) => _ == 2).value, [1, 3]); - expect(c.removeWhere((_) => _ == 3).value, [1, 2]); - expect(c.removeWhere((_) => _ == 4).value, [1, 2, 3]); - expect(c.value, [1, 2, 3]); - }); - - test('filter', () { - expect(a.filter((_) => _ == 1).value, [1]); - expect(a.filter((_) => _ == 2).value, []); - expect(a.value, [1]); - - expect(b.filter((_) => _ == 'q').value, ['q']); - expect(b.filter((_) => _ == 'w').value, []); - expect(b.value, ['q']); - - expect(c.filter((_) => _ == 1).value, [1]); - expect(c.filter((_) => _ == 2).value, [2]); - expect(c.filter((_) => 1 == _ || 2 == _).value, [1, 2]); - expect(c.filter((_) => 0 == (_ % 2)).value, [2]); - expect(c.value, [1, 2, 3]); - }); - - test('Add', () { - expect(a.add(1).value, [1, 1]); - expect(a.add(1).add(2).add(3).value, [1, 1, 2, 3]); - expect(a.value, [1]); - - expect(b.add('w').value, ['q', 'w']); - expect(b.value, ['q']); - }); - - group('+ operator', () { - test('With common types', () { - expect((a + 1).value, [1, 1]); - expect((a + 1 + 2 + 3).value, [1, 1, 2, 3]); - expect(a.value, [1]); - - expect((b + 'w').value, ['q', 'w']); - expect(b.value, ['q']); - }); - - test('With list', () { - expect((a + [2, 3]).value, [1, 2, 3]); - expect(a.value, [1]); - - expect((b + ['w', 'e']).value, ['q', 'w', 'e']); - expect(b.value, ['q']); - }); - }); - - test('Remove', () { - expect(a.remove(1).value, []); - expect(a.remove(0).value, [1]); - expect(a.value, [1]); - - expect(c.remove(1).value, [2, 3]); - expect(c.value, [1, 2, 3]); - }); - - group('- operator', () { - test('With common types', () { - expect((a - 1).value, []); - expect((a - 0).value, [1]); - expect(a.value, [1]); - - expect((c - 1).value, [2, 3]); - expect(c.value, [1, 2, 3]); - }); - - test('With common list', () { - expect((a - [1, 2]).value, []); - expect((a - [2]).value, [1]); - expect(a.value, [1]); - - expect((c - [1]).value, [2, 3]); - expect((c - [2, 3]).value, [1]); - expect(c.value, [1, 2, 3]); - }); - }); - - test('[] operator', () { - expect(a[0], 1); - expect(b[0], 'q'); - expect(c[0], 1); - expect(c[1], 2); - expect(c[2], 3); - }); - test('Tail', () { - expect(a.tail.value, []); - expect(b.tail.value, []); - expect(c.tail.value, [2, 3]); }); }