From 57225d4cae7421696a0147d5b1ef91fcbe961da7 Mon Sep 17 00:00:00 2001 From: Leon Strauss Date: Wed, 28 Jul 2021 00:05:52 +0200 Subject: [PATCH 1/3] :sparkles: Implement collections/sortBy and tests for it --- collections/sort_by.ts | 48 ++++++++++++++++ collections/sort_by_test.ts | 112 ++++++++++++++++++++++++++++++++++++ 2 files changed, 160 insertions(+) create mode 100644 collections/sort_by.ts create mode 100644 collections/sort_by_test.ts diff --git a/collections/sort_by.ts b/collections/sort_by.ts new file mode 100644 index 000000000000..e40e0973eb0d --- /dev/null +++ b/collections/sort_by.ts @@ -0,0 +1,48 @@ +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. + +/** + * Returns all elements in the given collection, sorted by their result using the given selector + * + * Example: + * + * ```typescript + * const people = [ + * { name: 'Anna', age: 34 }, + * { name: 'Kim', age: 42 }, + * { name: 'John', age: 23 }, + * ] + * const sortedByAge = sortBy(people, it => it.age) + * + * console.assert(sortedByAge === [ + * { name: 'John', age: 23 }, + * { name: 'Anna', age: 34 }, + * { name: 'Kim', age: 42 }, + * ]) + * ``` + */ +export function sortBy( + array: Array, + selector: + | ((el: T) => number) + | ((el: T) => string) + | ((el: T) => bigint) + | ((el: T) => boolean) + | ((el: T) => Date), +): Array { + const ret = Array.from(array) + + return ret.sort((a, b) => { + const selectedA = selector(a); + const selectedB = selector(b); + + if (selectedA > selectedB) { + return 1; + } + + if (selectedA < selectedB) { + return -1; + } + + return 0; + }); +} diff --git a/collections/sort_by_test.ts b/collections/sort_by_test.ts new file mode 100644 index 000000000000..db3ad3ec707d --- /dev/null +++ b/collections/sort_by_test.ts @@ -0,0 +1,112 @@ +// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. + +import { assertEquals } from "../testing/asserts.ts"; +import { sortBy } from "./sort_by.ts"; + +function sortByTest( + input: [ + Array, + | ((el: T) => number) + | ((el: T) => string) + | ((el: T) => bigint) + | ((el: T) => boolean) + | ((el: T) => Date), + ], + expected: Array, + message?: string, +) { + const actual = sortBy(...input); + assertEquals(actual, expected, message); +} + +Deno.test({ + name: "[collections/sortBy] no mutation", + fn() { + const array = ["a", "abc", "ba"]; + sortBy(array, (it) => it.length); + + assertEquals(array, ["a", "abc", "ba"]); + }, +}); + +Deno.test({ + name: "[collections/sortBy] empty input", + fn() { + sortByTest( + [[], () => 5], + [], + ); + }, +}); + +Deno.test({ + name: "[collections/sortBy] identity selector", + fn() { + sortByTest( + [ + [2, 3, 1], + (it) => it, + ], + [1, 2, 3], + ); + }, +}); + +Deno.test({ + name: "[collections/sortBy] sortings", + fn() { + const testArray = [ + { name: "benchmark", stage: 3 }, + { name: "test", stage: 2 }, + { name: "build", stage: 1 }, + { name: "deploy", stage: 4 }, + ]; + + sortByTest( + [ + testArray, + (it) => it.stage, + ], + [ + { name: "build", stage: 1 }, + { name: "test", stage: 2 }, + { name: "benchmark", stage: 3 }, + { name: "deploy", stage: 4 }, + ], + ); + sortByTest( + [ + testArray, + (it) => it.name, + ], + [ + { name: "benchmark", stage: 3 }, + { name: "build", stage: 1 }, + { name: "deploy", stage: 4 }, + { name: "test", stage: 2 }, + ], + ); + sortByTest( + [ + ["ba", "asdf"], + (it) => it.length < 3, + ], + ["asdf", "ba"], + ); + sortByTest( + [ + [ + "February 1, 2022", + "December 17, 1995", + "June 12, 2012", + ], + (it) => new Date(it), + ], + [ + "December 17, 1995", + "June 12, 2012", + "February 1, 2022", + ], + ); + }, +}); From 21c3562f2030ccb22a97dd0ff8879aba3a48942c Mon Sep 17 00:00:00 2001 From: Leon Strauss Date: Wed, 28 Jul 2021 12:28:44 +0200 Subject: [PATCH 2/3] :bug: Add import to test example in collections/sortBy --- collections/sort_by.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/collections/sort_by.ts b/collections/sort_by.ts index e40e0973eb0d..3fd08642109b 100644 --- a/collections/sort_by.ts +++ b/collections/sort_by.ts @@ -5,7 +5,9 @@ * * Example: * - * ```typescript + * ```ts + * import { sortBy } from "./sort_by.ts" + * * const people = [ * { name: 'Anna', age: 34 }, * { name: 'Kim', age: 42 }, From 4e6856ec158179e3619f2170fb99b93a51f104c2 Mon Sep 17 00:00:00 2001 From: Leon Strauss Date: Fri, 30 Jul 2021 15:07:01 +0200 Subject: [PATCH 3/3] :fire: Remove boolean selector from collections/sortBy --- collections/sort_by.ts | 11 +++++------ collections/sort_by_test.ts | 8 -------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/collections/sort_by.ts b/collections/sort_by.ts index 3fd08642109b..524da8329839 100644 --- a/collections/sort_by.ts +++ b/collections/sort_by.ts @@ -25,13 +25,12 @@ export function sortBy( array: Array, selector: - | ((el: T) => number) - | ((el: T) => string) - | ((el: T) => bigint) - | ((el: T) => boolean) - | ((el: T) => Date), + | ((el: T) => number) + | ((el: T) => string) + | ((el: T) => bigint) + | ((el: T) => Date), ): Array { - const ret = Array.from(array) + const ret = Array.from(array); return ret.sort((a, b) => { const selectedA = selector(a); diff --git a/collections/sort_by_test.ts b/collections/sort_by_test.ts index db3ad3ec707d..da0efebc5479 100644 --- a/collections/sort_by_test.ts +++ b/collections/sort_by_test.ts @@ -9,7 +9,6 @@ function sortByTest( | ((el: T) => number) | ((el: T) => string) | ((el: T) => bigint) - | ((el: T) => boolean) | ((el: T) => Date), ], expected: Array, @@ -86,13 +85,6 @@ Deno.test({ { name: "test", stage: 2 }, ], ); - sortByTest( - [ - ["ba", "asdf"], - (it) => it.length < 3, - ], - ["asdf", "ba"], - ); sortByTest( [ [