From b476299467487e474d8d513a0c79db6c30b563ef Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Fri, 9 Aug 2024 20:44:42 -0500 Subject: [PATCH] prog --- README.md | 83 ++++++++++++++++++++++++++++++++-------------- TODO.txt | 4 +++ src/comparators.ts | 8 +++-- src/equals.test.ts | 1 + src/equals.ts | 8 +++++ typedoc.json | 6 ++-- 6 files changed, 81 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 9095840..e8137e6 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,8 @@ # Compear 🍐🤷🍐 -_Flexible utilities for comparing and sorting anything in JavaScript_ +_Flexible utilities for comparing and sorting in JavaScript_ -Compear is inspired by Kotlin's [comparisons](kotlin.comparisons) package, but tailored for JavaScript. - -## Features - -* Create highly flexible sorting/comparing logic -* First-class TypeScript support with strong type safety -* Tiny source with zero dependencies +**[Documentation](https://camsteffen.github.io/compear/index.html)** ## Installation @@ -16,38 +10,79 @@ Compear is inspired by Kotlin's [comparisons](kotlin.comparisons) package, but t npm install compear ``` -### Functions +## What is it? + +Let's look at an example. +Suppose you have a list of objects (`people`)... + +```javascript +const people = [ + { name: "Tina" }, + { name: "Bob" }, + { name: "Lewis" }, +]; +``` + +...and you want to sort them by the `name` property. + +Without Compear: + +```javascript +const peopleSorted = people.toSorted((personA, personB) => { + if (personA.name < personB.name) return -1; + if (personA.name > personB.name) return 1; + return 0; +}); +``` + +With Compear: +```javascript +const peopleSorted = people.toSorted(compareBy((person) => person.name)); +``` -* [compareBy] +Notice in both examples we are using the same `array.toSorted(..)` function that is built-in to JavaScript. +The function that is passed as an argument to `array.toSorted(..)` is called a _comparator_. +The `compareBy` function from Compear helps to create a comparator. +Oftentimes `compareBy` is all you need, +but there are other utils for more advanced cases. -[compareBy]: localhost:1234 +Compear takes some inspiration from Kotlin's [kotlin.comparisons](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.comparisons/) package, but is designed for JavaScript. -#### `compareBy` +Compear is written in TypeScript and provides strong type safety. -asdfasdlk +## Usage -## Examples +Here are some more examples of what you can do with Compear: ```javascript +import { compareBy, compareByDesc, compareWith, minWith } from "compear"; + const heros = [ - { - name: "Stupendous Man", - favoriteColor: "red", - }, { name: "Frozone", + age: 37, favoriteColor: "blue", }, + { + name: "Stupendous Man", + age: 9, + favoriteColor: "red", + }, { name: "Iron Man", + age: 44, favoriteColor: "gold", }, -] -``` - -[kotlin.comparisons]: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.comparisons/ - - +]; +const youngestHero = minWith(heros, compareBy("age")) +const sortedByName = heros.sort(compareBy("name")); +const sortedByNameAndGoldFirst = heros.toSorted( + compareWith( + compareByDesc("favoriteColor", (color) => color === "gold"), + compareBy("name"), + ) +); +``` diff --git a/TODO.txt b/TODO.txt index 0c23ffe..8b1f017 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,3 +1,7 @@ name orderly, ofsorts, mete, finical, scrutiny, compadre, sorta, minymoe, dico raedme +drop equals? equals(anyObject, anyObject) == true :( +structural equals? +structural compare? + diff --git a/src/comparators.ts b/src/comparators.ts index f871764..784838c 100644 --- a/src/comparators.ts +++ b/src/comparators.ts @@ -7,9 +7,11 @@ import reverse from "./private/reverse"; /** * The default comparator which orders values in ascending order. * - * If the values are both iterables, then they are compared by their elements - * _recursively_ (see also {@link compareEachWith}). Otherwise, values are - * compared using the `<` or `>` operators. + * If the values are both [iterables] (e.g. Array or Map), then they are + * compared by their elements _recursively_ (see also {@link compareEachWith}). + * Otherwise, values are compared using the `<` or `>` operators. + * + * [iterables]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_generators#iterables */ export function naturalOrder(a: unknown, b: unknown): number { if (a === b) return 0; diff --git a/src/equals.test.ts b/src/equals.test.ts index 0949d5d..1521bb2 100644 --- a/src/equals.test.ts +++ b/src/equals.test.ts @@ -8,6 +8,7 @@ describe("equals", () => { { a: 0, b: 1, expected: false }, { a: [1], b: [1], expected: true }, { a: [1], b: [1, 2], expected: false }, + { a: {}, b: {}, expected: true }, ])("equals($a, $b) -> $expected", ({ a, b, expected }) => { expect(equals(a, b)).toBe(expected); }); diff --git a/src/equals.ts b/src/equals.ts index 21cf5ae..f3a33c7 100644 --- a/src/equals.ts +++ b/src/equals.ts @@ -7,6 +7,14 @@ import { naturalOrder } from "./comparators"; * You may optionally provide a comparator as a third argument. Otherwise, * {@link naturalOrder} will be used by default. * + * @example + * ```javascript + * equals(1, 1) // -> true + * equals(1, 2) // -> false + * equals({ foo: 'bar' }, { foo: 'bar' }) // -> false + * equals({ foo: 'bar' }, { foo: 'bar' }, compareBy('foo')) // -> true + * ``` + * * @param a the first value to compare * @param b the second value to compare * @param comparator used to compare the values diff --git a/typedoc.json b/typedoc.json index 1d44c4d..afd0f40 100644 --- a/typedoc.json +++ b/typedoc.json @@ -2,7 +2,9 @@ "$schema": "https://typedoc.org/schema.json", "entryPoints": ["./src/index.ts"], "name": "Compear", - "plugin": ["typedoc-material-theme"], "customCss": "./docs.css", - "skipErrorChecking": true + "skipErrorChecking": true, + "navigationLinks": { + "github": "https://github.com/camsteffen/compear" + } }