kt_dart 0.8.0-dev.1

  • Readme
  • Changelog
  • Example
  • Installing
  • 95

kt.dart #

Pub codecov

This project is a port of Kotlin's Kotlin Standard library for Dart/Flutter projects. It's a useful addition to dart:core and includes collections (KtList, KtMap, KtSet) as well as other packages which can improve every Dart/Flutter app.

Motivation #

Dart's dart:core package provides basic building blocks. But sometimes they are too low level and not as straightforward as Kotlin's kotlin-stdlib.

Here are a few examples of what this project offers: (click to expand)

Immutable collections by default

dart:core collections #

Dart's List is mutable by default. The immutable List.unmodifiable is the same type, but the mutation methods throw at runtime.

final dartList = [1, 2, 3];
dartList.add(4); // mutation is by default possible
assert(dartList.length == 4);

final immutableDartList = List.unmodifiable(dartList);
immutableDartList.add(5); // throws: Unsupported operation: Cannot add to an unmodifiable list

Dart's mutable List is indistinguishable from an immutable List which might cause errors.

void addDevice(List<Widget> widgets, Device device) {
  // no way to check whether widgets is mutable or not
  // add might or might now throw
  widgets.add(_deviceRow());
  widgets.add(Divider(height: 1.0));
}

kt_dart collections #

KtList and KtMutableList are two different Types. KtList is immutable by default and has no mutation methods (such as add). Methods like map((T)->R) or plusElement(T) return a new KtList leaving the old one unmodified.

final ktList = listOf(1, 2, 3);
// The method 'add' isn't defined for the class 'KtList<int>'.
ktList.add(4); // compilation error
       ^^^

// Adding an item returns a new KtList
final mutatedList = ktList.plusElement(4);
assert(ktList.size == 3);
assert(mutatedList.size == 4);

KtMutableList offers mutation methods where the content of that collection can be actually mutated. I.e. with remove(T) or add(T);

// KtMutableList allow mutation
final mutableKtList = mutableListOf(1, 2, 3);
mutableKtList.add(4); // works!
assert(mutableKtList.size == 4);

All collection types have mutable counterparts:

ImmutableMutable
KtListKtMutableList
KtSetKtMutableSet, KtHashSet, KtLinkedSet
KtMapKtMutableMap, KtHashMap, KtLinkedMap
KtCollectionKtMutableCollection and all the above
KtIterableKtMutableIterable and all the above
Deep equals

dart:core collections #

Dart's List works like a Array in Java. Equals doesn't compare the items; it only checks the identity. To compare the contents you have to use helper methods methods from 'package:collection/collection.dart'.

// Comparing two Dart Lists works only by identity
final a = [1, 2, 3, 4];
final b = [1, 2, 3, 4];
print(a == b); // false, huh?

// Content-based comparisons require unnecessary glue code
Function listEq = const ListEquality().equals;
print(listEq(a, b)); // true

// MapEquality isn't deep by default
final x = {1: ["a", "b", "c"], 2: ["xx", "yy", "zz"]};
final y = {1: ["a", "b", "c"], 2: ["xx", "yy", "zz"]};
Function mapEq = const MapEquality().equals;
print(mapEq(x, y)); // false, wtf?!

Function deepEq = const DeepCollectionEquality().equals;
print(deepEq(x, y)); // true, finally

kt_dart collections #

KtList and all other collection types implement equals by deeply comparing all items.

final a = listOf(1, 2, 3, 4);
final b = listOf(1, 2, 3, 4);
print(a == b); // true, as expected

final x = mapFrom({1: listOf("a", "b", "c"), 2: listOf("xx", "yy", "zz")});
final y = mapFrom({1: listOf("a", "b", "c"), 2: listOf("xx", "yy", "zz")});
print(x == y); // deep equals by default
Common methods

Some of Dart's method names feel unfamiliar. That's because modern languages and frameworks (Kotlin, Swift, TypeScript, ReactiveExtensions) kind of agreed on naming methods when it comes to collections. This makes it easy to switch platforms and discuss implementations with coworkers working with a different language.

expand -> flatMap #

final dList = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
final kList = listOf(listOf(1, 2, 3), listOf(4, 5, 6), listOf(7, 8, 9));

// dart:core
final dFlat = dList.expand((l) => l).toList();
print(dFlat); // [1, 2, 3, 4, 5, 6, 7, 8, 9]

// kt_dart
final kFlat = kList.flatMap((l) => l);
print(kFlat); // [1, 2, 3, 4, 5, 6, 7, 8, 9]

where -> filter #

final dNames = ["Chet", "Tor", "Romain", "Jake", "Dianne"];
final kNames = listFrom(dNames);

// dart:core
final dShortNames = dNames.where((name) => name.length <= 4).toList();
print(dShortNames); // [Chet, Tor, Jake]

// kt_dart
final kShortNames = kNames.filter((name) => name.length <= 4);
print(kShortNames); // [Chet, Tor, Jake]

firstWhere -> first, firstOrNull #

final dNames = ["Chet", "Tor", "Romain", "Jake", "Dianne"];
final kNames = listFrom(dNames);

// dart:core
dNames.firstWhere((name) => name.contains("k")); // Jake
dNames.firstWhere((name) => name.contains("x"), orElse: () => null); // null
dNames.firstWhere((name) => name.contains("x"), orElse: () => "Nobody"); // Nobody

// kt_dart
kNames.first((name) => name.contains("k")); // Jake
kNames.firstOrNull((name) => name.contains("x")); // null
kNames.firstOrNull((name) => name.contains("x")) ?? "Nobody"; // Nobody

KtList #

KtList is a read-only list of elements. It is immutable because it doesn't offer mutation methods such as remove or add. Use KtMutableMap if you want to use a mutable list.

To create a KtList/KtMutableList use the KtList.of constructor or convert an existing Dart List to a KtList with the list.toImmutableList() extension.

Create a KtList #

// Create a KtList from scratch
final beatles = KtList.of("John", "Paul", "George", "Ringo");

// Convert a existing List to KtList
final abba = ["Agnetha", "Björn", "Benny", "Anni-Frid"];
final immutableAbba = abba.toImmutableList();

Create a KtMutableList #

KtList is immutable by default, which means it doesn't offer methods like add or remove. To create mutable list with kt_dart use the KtMutableList constructor.

// Create a KtMutableList from scratch
final beatles = KtMutableList.of("John", "Paul", "George", "Ringo");
beatles.removeAt(0);
print(beatles); // [Paul, George, Ringo]

Mutable/Immutable conversion #

Conversions between KtList and KtMutableList can be done with KtList.toMutableList() and KtMutableList.toList();

final beatles = KtList.of("John", "Paul", "George", "Ringo");
final mutable = beatles.toMutableList();
mutable.removeAt(0);
print(mutable); // [Paul, George, Ringo]
print(beatles); // [John, Paul, George, Ringo]

for loop #

kt_dart collections do not implement Iterable. It is therefore not possible to directly iterate over the entries of a KtList.

All kt_dart collections offer a .iter property which exposes a Dart Iterable. For-loops therefore don't look much different.

final beatles = KtList.of("John", "Paul", "George", "Ringo");
for (final member in beatles.iter) {
  print(member);
}

Yes, alternatively you could use .asList() instead which returns a Dart List.

Kotlin syntax #

Kotlin users might be more familiar with the listOf() and mutableListOf() functions. Use them if you like but keep in mind that the dart community is much more used to use constructors instead of top-level functions.

final beatles = listOf("John", "Paul", "George", "Ringo");
final abba = mutableListOf("Agnetha", "Björn", "Benny", "Anni-Frid");

KtSet #

A KtSet is a unordered collection of elements without duplicates.

Creating a KtSet/KtMutableSet is very similar to the KtList API.

// Create a KtSet from scratch
final beatles = KtSet.of("John", "Paul", "George", "Ringo");

// Convert a existing Set to KtSet
final abba = {"Agnetha", "Björn", "Benny", "Anni-Frid"};
final immutableAbba = abba.toImmutableSet();

KtMap #

To create a KtMap/KtMutableMap start with Dart Map and then convert it to a KtMap with either:

  • pokemon.toImmutableMap(): KtMap (since Dart 2.7)
  • KtMap.from(pokemon): KtMap
  • pokemon.kt: KtMutableMap (since Dart 2.7)
  • KtMutableMap.from(pokemon): KtMutableMap
// immutable
final pokemon = {
  1: "Bulbasaur",
  2: "Ivysaur",
  3: "Stegosaur",
}.toImmutableMap();

final newPokemon = KtMap.from({
  152: "Chikorita",
  153: "Bayleef",
  154: "Meganium",
});

// mutable
final mutablePokemon = {
  1: "Bulbasaur",
  2: "Ivysaur",
  3: "Stegosaur",
}.kt;

final newMutablePokemon = KtMutableMap.from({
  152: "Chikorita",
  153: "Bayleef",
  154: "Meganium",
});

KtHashMap and KtLinkedMap #

You may want to use a specific Map implementation. kt_dart offers:

  • KtLinkedMap - based on Darts LinkedHashMap where the insertion order of keys is remembered and keys are iterated in the order they were inserted into the map
  • KtHashMap - based on Darts HashMap where keys of a HashMap must have consistent [Object.==] and [Object.hashCode] implementations. Iterating the map's keys, values or entries (through [forEach]) may happen in any order.

KtPair, KtTriple #

kt_dart offer two types of tuples, KtPair with two elements and KtTriple with three elements. They are used by some collection APIs and prevent a 3rd party dependency.

final beatles = KtList.of("John", "Paul", "George", "Ringo");
final partitions = beatles.partition((it) => it.contains("n"));
print(partitions.first); // [John, Ringo]
print(partitions.second); // [Paul, George]

There won't be a KtQuadruple or TupleN in this library. If you want to use tuples heavily in you application consider using the tuple package. Better, use freezed to generated data classes which makes for a much better API.

Annotations #

@nullable #

Kotlin already has Non-Nullable types, something which is coming to Dart soon™. kt_dart already makes use of Non-Nullable Types and never returns null unless a method is annotated with @nullable.

https://github.com/passsy/kt.dart/blob/490a3b205ffef27d9865d6018381a4168119e69f/lib/src/collection/kt_map.dart#L51-L53

There isn't any tooling which will warn you about the wrong usage but at least it's documented. And once nnbd lands in Dart it will be fairly easy to convert.

@nonNull #

This annotation annotates methods which never return null. Although this is the default in kt_dart, is makes it very obvious for methods which sometimes return null in other languages.

@experimental #

A method/class annotated with @experimental marks the method/class as experimental feature. Experimental APIs can be changed or removed at any time.

License #

Copyright 2019 Pascal Welsch

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

0.8.0-dev.1 #

  • #124 KtList.of and KtSet.of now allow null as parameters. Same for listOf and setOf
  • #120 Standard extensions let, also, takeIf and takeUnless
  • #120 TODO([String message]) top-level function which throws NotImplementedException
  • #120 repeat(int times, void Function(int) action) top-level function
  • #126 Allow const .empty() constructors for KtList, KtMap and KtSet (Thanks @TimWhiting)
  • #127 plus, minus operator overrides for KtSet, returning KtSet and not KtList as the KtIterable operators do

0.7.0+1 #

  • Fix unused import

0.7.0 #

The library has be upgrade to use Static Extension Methods.

Interop #

This update also includes extensions for Dart collections which allow easy interoperability between dart and kt.dart collections using the .kt and .dart getters.

  // New: Converting dart collections to KtDart collections (mutable views)
  final KtMutableList<String> ktList = ["hey"].kt;
  final KtMutableSet<String> ktSet = {"hey"}.kt;
  final KtMutableMap<String, int> ktMap = {"hey": 1}.kt;

  // Converting KtDart collections to dart collections
  final List<String> dartList = KtList.of("hey").dart;
  final Set<String> dartSet = KtSet.of("hey").dart;
  final Map<String, int> dartMap = KtMap.from({"hey": 1}).dart;

Note: ["Hello", "World"].kt returns a KtMutableList<String> and mutations are reflected on the original dart list. It is not a copy! Because it doesn't copy it is very cheap and only syntax sugar.

To convert dart collections to their immutable kt.dart counterparts use: .toImmutableList(), .toImmutableSet(), .toImmutableMap()

  // New: Make dart collections immutable
  final KtList<String> list = ["hey"].toImmutableList();
  final KtSet<String> set = {"hey"}.toImmutableSet();
  final KtMap<String, int> map = {"hey": 1}.toImmutableMap();

Possible breaking changes #

  • Relax sortBy/sortByDescending, maxBy/minBy typing to work better with ints and doubles #116
// Was: int doesn't not implement Comparable<int> but Comparable<num>
// minBy therefore required some help to figure out the correct type (<num>) 
users.minBy<num>((it) => it.age);

// Now: minBy doesn't require the Comparable (num) to have the same same as the value (int).
users.minBy((it) => it.age);
  • Remove unnecessary generic R from KtIterable.zipWithNext #118

New Extensions #

  • KtPair and KtTriple now have a new toList() function to convert the values to a KtList
  • KtList?.orEmpty() returns an empty list when the list is null
  • KtSet?.orEmpty() returns an empty set when the set is null
  • KtMap?.orEmpty() returns an empty map when the map is null
  • KtMap.ifEmpty(() -> defaultValue) returns the default value when the map is empty
  • KtIterable<KtIterable<T>>.flatten() flattens the nested collections to KtIterable<T>
  • KtIterable<KtPair<T, U>>.unzip(): KtPair<KtList<T>, KtList<U>> unzips list of pairs to list of their first and second values
  • KtIterable<Comparable<T>>.min() returns the smallest element of any comparable iterable
  • KtIterable<Comparable<T>>.max() returns the largest element of any comparable iterable

0.7.0-dev.4 #

  • New extension Iterable.toImmutableList(): KtList
  • New extension Iterable.toImmutableSet(): KtSet
  • New extension KtIterable<num>.average(): double
  • Relax sortBy/sortByDescending, maxBy/minBy typing to work better with ints and doubles
// Was: int doesn't not implement Comparable<int> but Comparable<num>
// minBy therefore required some help to figure out the correct type (<num>) 
users.minBy<num>((it) => it.age);

// Now: minBy doesn't require the Comparable (num) to have the same same as the value (int).
users.minBy((it) => it.age);

0.7.0-dev.3 #

  • Rename (List|Set|Map).immutable() extension to .toImmutableList() to match Dart SDK naming schema.
  • Remove int.rangeTo(X) extension. Please use the dartx as replacement which offers the same extension
  • Remove T.to(X) extension to create a KtPair. It's too general and should be offered by the dart SDK not a 3rd party package

0.7.0-dev.2 #

New .dart extensions to convert KtDart collections back to dart collections.

  // New: Converting dart collections to KtDart collections (mutable views)
  final KtMutableList<String> ktList = ["hey"].kt;
  final KtMutableSet<String> ktSet = {"hey"}.kt;
  final KtMutableMap<String, int> ktMap = {"hey": 1}.kt;

  // Converting KtDart collections to dart collections
  final List<String> dartList = KtList.of("hey").dart;
  final Set<String> dartSet = KtSet.of("hey").dart;
  final Map<String, int> dartMap = KtMap.from({"hey": 1}).dart;

0.7.0-dev.1 #

KtDart makes full use of darts static extension methods, introduced with Dart 2.6.

The public API stays unchanged and is backwards compatible.

Improved interopt with dart collections #

It is now easier then ever to convert dart to ktdart collections and vice versa. Use the .kt property to convert dart collections to KtDart collections. (Note: .kt create a view, which allows you to mutate the original dart collection).

  // New: Make dart collections immutable
  final KtList<String> list = ["hey"].immutable();
  final KtSet<String> set = {"hey"}.immutable();
  final KtMap<String, int> map = {"hey": 1}.immutable();

  // New: Converting dart collections to KtDart collections (mutable views)
  final KtMutableList<String> ktList = ["hey"].kt;
  final KtMutableSet<String> ktSet = {"hey"}.kt;
  final KtMutableMap<String, int> ktMap = {"hey": 1}.kt;

  // Converting KtDart collections to dart collections
  final List<String> dartList = KtList.of("hey").asList();
  final Set<String> dartSet = KtSet.of("hey").asSet();
  final Map<String, int> dartMap = KtMap.from({"hey": 1}).asMap();

Tuple improvements #

KtPairs can now created with the T0.to(T1) extension.

final KtPair<String, int> pair = "foo".to(42);

Also, KtPair and KtTriple now have a new toList() function to convert the values to a KtList.

New Extensions #

  • KtList?.orEmpty() returns an empty list when the list is null
  • KtSet?.orEmpty() returns an empty set when the set is null
  • KtMap?.orEmpty() returns an empty map when the map is null
  • KtMap.ifEmpty(() -> defaultValue) returns the default value when the map is empty
  • KtIterable<KtIterable<T>>.flatten() flattens the nested collections to KtIterable<T>
  • KtIterable<KtPair<T, U>>.unzip(): KtPair<KtList<T>, KtList<U>> unzips list of pairs to list of their first and second values
  • KtIterable<Comparable<T>>.min() returns the smallest element of any comparable iterable
  • KtIterable<Comparable<T>>.max() returns the largest element of any comparable iterable

0.6.2 #

diff v0.6.1...v0.6.2

  • #96 Dart 2.0.0 comparability. (Was only Dart 2.1.0 compatible).
  • #97 Fix broken links to lib classes in documentation
  • #97 Adjust analyzer rules. Add new ones and explain why others aren't active. Adjusted the code accordingly

0.6.1 #

diff v0.6.0...v0.6.1

  • #92 Improve pub score by changing comments to ///

0.6.0 #

diff v0.5.0...v0.6.0

This major update of kt.dart add 10+ extension methods for KtMap and makes working with maps even easier.

Behavior Changes #

The properties KtList.list: List,KtSet.set: Set are now deprecated and KtMap.map: Map was removed. Those properties where used to convert kt.dart collections to dart collections. Instead use the new KtList.asList(): List, KtSet.asSet(): Set, KtMa.asMap(): Map methods. The old properties returned copies of the collections. The new as-methods return views of the original collections and reflect changes of the original data.

This breaking change was necessary because the property KtMap.map: Map<K, V> was conflicting with KtMap.map(MapEntry<K, V> -> R) : KtList<R> to map the entries to items of a KtList. Read about further details here.

If you have used properties to iterate over the collections using a for-loop you should now always use iter which is available for all kt.dart collections.

for (final element in listOf("a", "b", "c").iter) {
  print(element); 
}
for (final element in setOf("a", "b", "c").iter) {
  print(element); 
}
for (final p in mapFrom({1: "Bulbasaur", 2: "Ivysaur"}).iter) {
  print("${p.key} -> ${p.value}"); 
}

Additions #

  • #86 New: KtMap.map Returns a list containing the results of applying the given transform function to each entry in the original map.
  • #86 New: KtMap.iter Access to a Iterable to be used in for-loops
  • #87 New: KtMap.count Returns the number of entries matching the given [predicate] or the number of entries when predicate = null.
  • #89 New: KtMap.minBy Returns the first entry yielding the smallest value of the given function or null if there are no entries.
  • #89 New: KtMap.minWith Returns the first entry having the smallest value according to the provided comparator or null if there are no entries.
  • #89 New: KtMap.maxBy Returns the first entry yielding the largest value of the given function or null if there are no entries.
  • #89 New: KtMap.maxWith Returns the first entry having the largest value according to the provided comparator or null if there are no entries.
  • #90 New: KtMap.toList Returns a KtList containing all key-value pairs.
  • #78 New: KtMap.forEach Performs given action on each key/value pair from this map. thanks @acherkashyn
  • #80 New: KtMap.none Returns true if there is no entries in the map that match the given predicate. thanks @acherkashyn
  • #80 New: KtMap.all Returns true if all entries match the given predicate. thanks @acherkashyn
  • #80 New: KtMap.any Returns true if there is at least one entry that matches the given predicate. thanks @acherkashyn
  • #84 New: KtMap.filterKeys Returns a map containing all key-value pairs with keys matching the given predicate.
  • #84 New: KtMap.filterValues Returns a map containing all key-value pairs with values matching the given predicate.
  • #79 New: KtMap.asMap Returns a read-only dart:core Map
  • #79 New: KtMutableMap.asMap Creates a Map instance that wraps the original KtMap. It acts as a view.

  • #75 New: KtIterable.takeWhile Returns a list containing first elements satisfying the given predicate.
  • #76 New: KtIterable.takeLastWhile Returns a list containing last elements satisfying the given predicate.

  • #73 New: KtList.takeLast, Returns a list containing last n elements.
  • #79 New: KtList.asList Returns a read-only dart:core List
  • #79 New: KtMutableList.asList Creates a List instance that wraps the original KtList. It acts as a view.

  • #79, #91 New: KtSet.asSet Returns a read-only dart:core Set
  • #79 New: KtMutableSet.asSet Creates a Set instance that wraps the original KtSet. It acts as a view.

Bugfixes #

  • #74 Fix: KtList.dropLastWhile was off by 1
  • #88 Fix: KtIterable.minWith returned the max value

Documentation #

  • #68 Document KtSet constructors
  • #70 Fix README typos, thanks @RedBrogdon

Misc. #

  • #69 KtMutableListIterator throws IndexOutOfBoundsException when calling set before next was called
  • #81 Force dartfmt on CI
  • #83 Improve .gitignore

0.5.0 #

diff v0.4.2...v0.5.0

Project has been renamed to kt.dart. If you're using a previous version upgrade like this:

pubspec.yaml

dependencies:
-  dart_kollection: ^0.3.0
-  kotlin_dart: ^0.4.0
+  kt_dart: ^0.5.0

your_source.dart

- import 'package:dart_kollection/dart_kollection.dart';
- import 'package:kotlin_dart/kotlin.dart';
+ import 'package:kt_dart/kt.dart';
  • #66 Rename KPair -> KtPair and KTriple -> KtTriple
  • #67 Rename package kotlin_dart -> kt_dart

0.4.3 #

diff v0.4.2...v0.4.3

Deprecate package kotlin_dart and recommend users to migrate to kt_dart.

0.4.2 #

diff v0.4.1...v0.4.2

Shorten pub project description to make pana happy.

0.4.1 #

diff v0.4.0...v0.4.1

Improve Readme which renders correctly on pub.

0.4.0 #

diff v0.3.0...v0.4.0

The kollection project was migrated to kotlin.dart where kollection becomes the collection module.

Upgrade #

pubspec.yaml

dependencies:
-  dart_kollection: ^0.3.0
+  kotlin_dart: ^0.4.0

your_source.dart

- import 'package:dart_kollection/dart_kollection.dart';
+ import 'package:kotlin_dart/kotlin.dart';

Breaking Changes #

  • #64 The class prefix of all collections has been changed from K to Kt (KList -> KtList)
  • #60 listOf now accepts up to 10 non-null arguments instead of an Iterable. Use listFrom to create KtLists from an dart Iterables
  • #60 Collections can now be created with factory constructors i.e. KtList.of(1, 2 ,3). Both APIs, factory constructor and function based one, are equally supported. It only depends on your personal taste.

Here is a list of all collection creation APIs.

Kotlin like, function based syntax

  /// List
  // Create immutable lists
  emptyList<int>();
  listOf(1, 2, 3, 4, 5);
  listFrom([1, 2, 3, 4, 5]);
  // Create mutable lists
  mutableListOf(1, 2, 3, 4, 5);
  mutableListFrom([1, 2, 3, 4, 5]);
  
  /// Set
  // Create immutable sets
  emptySet<int>();
  setOf(1, 2, 3, 4, 5);
  setFrom([1, 2, 3, 4, 5]);
  // Create a mutable set which keeps the order of the items
  linkedSetOf(1, 2, 3, 4, 5);
  linkedSetFrom([1, 2, 3, 4, 5]);
  // Create mutable, unordered hash-table based set
  hashSetOf(1, 2, 3, 4, 5);
  hashSetFrom([1, 2, 3, 4, 5]);
  
  /// Map
  // Create immutable maps
  emptyMap<int, String>();
  mapFrom({1: "a", 2: "b"});
  // Create mutable maps
  mutableMapFrom({1: "a", 2: "b"});
  // Create mutable maps without specified order when iterating over items
  hashMapFrom({1: "a", 2: "b"});
  // Create mutable maps which keep the order of the items
  linkedMapFrom({1: "a", 2: "b"});

Dart like, constructor based syntax

  /// List
  // Create immutable lists
  KList<int>.empty();
  KList.of(1, 2, 3, 4, 5);
  KList.from([1, 2, 3, 4, 5]);
  // Create mutable lists
  KMutableList<int>.empty();
  KMutableList.of(1, 2, 3, 4, 5);
  KMutableList.from([1, 2, 3, 4, 5]);
  
  /// Set
  // Create immutable sets
  KSet<int>.empty();
  KSet.of(1, 2, 3, 4, 5);
  KSet.from([1, 2, 3, 4, 5]);
  // Create a mutable set which keeps the order of the items
  KMutableSet<int>.empty();
  KMutableSet.of(1, 2, 3, 4, 5);
  KMutableSet.from([1, 2, 3, 4, 5]);
  // Create mutable, unordered hash-table based set
  KHashSet<int>.empty();
  KHashSet.of(1, 2, 3, 4, 5);
  KHashSet.from([1, 2, 3, 4, 5]);
  // Create a mutable set which keeps the order of the items
  KLinkedSet<int>.empty();
  KLinkedSet.of(1, 2, 3, 4, 5);
  KLinkedSet.from([1, 2, 3, 4, 5]);
  
  /// Map
  // Create mutable maps
  KMutableMap<int, String>.empty();
  KMutableMap.from({1: "a", 2: "b"});
  // Create mutable maps without specified order when iterating over items
  KHashMap<int, String>.empty();
  KHashMap.from({1: "a", 2: "b"});
  // Create mutable maps which keep the order of the items
  KLinkedMap<int, String>.empty();
  KLinkedMap.from({1: "a", 2: "b"});

0.3.2 #

diff v0.3.1...v0.3.12

Deprecate package dart_kollection in favour of kt_dart

0.3.1 #

diff v0.3.0...v0.3.1

Deprecate all APIs and advise users to upgrade to kotlin.dart

0.3.0 #

diff v0.2.0...v0.3.0

Summary #

This release of Kollection fully covers the project with unit tests, from 52% to 99% 🎉. By doing that bugs where discovered and fixed.

Because Dart doesn't support non-nullable types yet, this update manually checks all method arguments at runtime. Passing null in any method will throw ArgumentError unless documented otherwise.

Behavior changes #

  • #36 All method arguments are now validated for nullability. If a argument isn't documented as "nullable" the method will throw ArgumentError (when asserts are enabled)
  • #51, #46 KIterable<T>.associateWithTo, Kiterable<T>.filterTo, KIterable<T>.filterIndexedTo, KIterable<T>.filterNotTo, KIterable<T>.filterNotNullTo , KIterable<T>.groupByTo ,KMap<T>.mapKeysTo ,KMap<T>.mapValuesTo, KIterable.toCollection did not compile when called directly due to dart-lang/sdk/issues/35518. The type of destination of those methods has been changed to a dynamic type (i.e. KMutableList<T> -> KMutableList<dynamic>). Those methods will now be checked at runtime. This has one advantage: It allows to pass in contravariant types.
final KIterable<int> iterable = listOf([4, 25, -12, 10]);
final result = mutableListOf<num>(); // covariant!
final filtered = iterable.filterIndexedTo(result, (i, it) => it < 10);
expect(identical(result, filtered), isTrue);
expect(result, listOf([4, -12]));
  • #56 KMutableEntry.setValue now throws UnimplementedError because of bug #55. It anyways never worked.
  • #58 KSet doesn't allow mutation of its elements with via set getter. It is now really immutable.

API changes #

Bug fixes #

Documentation changes #

  • #57 Document hashSetOf and linkedSetOf
  • #19 KIterable.any document return value when called without predicate
  • #51 Document expected type of now dynamically typed KIterable<T>.associateWithTo, Kiterable<T>.filterTo, KIterable<T>.filterIndexedTo, KIterable<T>.filterNotTo, KIterable<T>.filterNotNullTo , KIterable<T>.groupByTo ,KMap<T>.mapKeysTo ,KMap<T>.mapValuesTo, KIterable.toCollection

Other changes #

0.2.0 #

diff v0.1.0...v0.2.0

Behavior change #

  • #6 Breaking: KMutableIterator.remove now throws UnimplementedError because of bug #5

API changes #

  • #1 Add Set<T> get set returning the internal dart set
  • #1 Add Map<K, V> get map returning the intenral dart set
  • #7 Add KMap.toMap and KMap.toMutableMap
  • #8 Add KMap.isNotEmpty
  • 3e3228e Add KMap.toString()
  • #9 Add Map.plus, Map.minus and operator +(KMap<K, V> map), operator -(K key)
  • #12 Remove const constructors from collection interfaces
  • #13 Remove default implementations from collection interfaces

Documentation changes #

  • #15 Add documentation for compareBy and compareByDescending

Other changes #

  • #2 Travis CI #2
  • #3, #4 Code coverage
  • #10 Test KMutableList.fill
  • #11 Test KPair, KTriple
  • #14 Test Exceptions
  • #15 Test Comparators naturalOrder(), reverseOrder()
  • #15 Test reverse(Comparator) util function
  • 6dd0d85 Reformatted with dartfmt (80 chars)

0.1.0 #

Initial release for

  • KList/KMutableList
  • KSet/KMutableSet
  • KMap/KMutableMap

with tons of extensions waiting for you to use them!

example/main.dart

// ignore_for_file: avoid_print
import "package:kt_dart/kt.dart";

void main() {
  /// Lists
  final mapped = listOf(1, 2, 3, 4).map((it) => ">$it<");
  print(mapped); // [>1<, >2<, >3<, >4<]

  final flatMapped = listOf(1, 2, 3, 4).flatMap((it) => listOf(it * 2, it * 3));
  print(flatMapped); // [2, 3, 4, 6, 6, 9, 8, 12]

  final filtered = flatMapped.filter((it) => it % 3 == 0);
  print(filtered); // [3, 6, 6, 9, 12]

  final distinct = listFrom([1, 2, 3, 1, 2, 3]).distinct();
  print(distinct); //[1, 2, 3]

  /// Better equals
  final kListEquals = listOf(12, 9, 6, 3) == listOf(12, 9, 6, 3);
  print(kListEquals); // true

  final dartListEquals = [12, 9, 6, 3] == [12, 9, 6, 3];
  print(dartListEquals); // false

  final kMapEquals = mapFrom({1: "Bulbasaur", 2: "Ivysaur"}) ==
      mapFrom({1: "Bulbasaur", 2: "Ivysaur"});
  print(kMapEquals); // true

  final dartMapEquals =
      {1: "Bulbasaur", 2: "Ivysaur"} == {1: "Bulbasaur", 2: "Ivysaur"};
  print(dartMapEquals); // false

  /// Sets
  print(setOf(1, 2, 3, 1, 2, 3)); // [1, 2, 3]

  /// Maps
  final pokemon = mutableMapFrom({
    1: "Bulbasaur",
    2: "Ivysaur",
  });
  pokemon[1] = "Ditto";
  print(pokemon); // {1=Ditto, 2=Ivysaur}

  /// Tons of useful operators which *should* be part of the dart std lib
  final numbers = listOf(1, 2, 3, 4);
  print(numbers.sum()); // 10

  final numbers5 = listOf(1, 2, 3, 4).sortedDescending();
  print(numbers5); // [4, 3, 2, 1]

  final beatles = setOf("John", "Paul", "George", "Ringo");
  print(beatles); // [John, Paul, George, Ringo]
  print(beatles.joinToString(
      separator: "/",
      transform: (it) => it.toUpperCase())); // JOHN/PAUL/GEORGE/RINGO

  final grouped = beatles.groupBy((it) => it.length);
  print(grouped); // {4=[John, Paul], 6=[George], 5=[Ringo]}
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  kt_dart: ^0.8.0-dev.1

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter pub get

Alternatively, your editor might support pub get or flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:kt_dart/annotation.dart';
import 'package:kt_dart/collection.dart';
import 'package:kt_dart/exception.dart';
import 'package:kt_dart/kt.dart';
import 'package:kt_dart/standard.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
92
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
95
Overall:
Weighted score of the above. [more]
95
Learn more about scoring.

We analyzed this package on Jun 11, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.8.4
  • pana: 0.13.9+1

Maintenance suggestions

Package is pre-release. (-5 points)

Pre-release versions should be used with caution; their API can change in breaking ways.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.6.0 <3.0.0
Dev dependencies
lint ^1.0.0
test ^1.0.0