diff --git a/lib/src/collection/kt_collection.dart b/lib/src/collection/kt_collection.dart index f7d4ccc..743eab7 100644 --- a/lib/src/collection/kt_collection.dart +++ b/lib/src/collection/kt_collection.dart @@ -36,6 +36,16 @@ extension KtCollectionExtensions on KtCollection { return elementAt(r.nextInt(size)); } + /// Returns a random element from this collection. + /// + /// returns null if this collection is empty. + T? randomOrNull([math.Random? random]) { + final r = random ?? math.Random(); + final index = r.nextInt(size); + if (index >= size) return null; + return elementAt(index); + } + /// Returns a [KtMutableList] filled with all elements of this collection. KtMutableList toMutableList() => KtMutableList.from(iter); } diff --git a/test/collection/collection_test.dart b/test/collection/collection_test.dart index 291e278..06360b5 100644 --- a/test/collection/collection_test.dart +++ b/test/collection/collection_test.dart @@ -140,6 +140,32 @@ void testCollection(KtCollection Function() emptyCollection, }); }); + group("randomOrNull", () { + test("random item or null with random parameter", () { + final collection = collectionOf(["a", "b", "c"]); + + final firstPick = collection.randomOrNull(NotRandom()..next = 2); + final pos2 = collection.elementAt(2); + if (ordered) expect(pos2, "c"); + + expect(firstPick, pos2); + + final pos0 = collection.elementAt(0); + if (ordered) expect(pos0, "a"); + + final secondPick = collection.randomOrNull(NotRandom()..next = 0); + expect(secondPick, pos0); + + final outOfRangePick = collection.randomOrNull(NotRandom()..next = 3); + expect(outOfRangePick, null); + }); + + test("randomOrNull works without passing a Random", () { + final collection = collectionOf(["a", "b", "c"]); + expect(collection.randomOrNull(), + anyOf(equals("a"), equals("b"), equals("c"), equals(null))); + }); + }); group("toString", () { if (ordered) { test("default string representation", () {