rbuckton / iterable-query

Query API over JavaScript (ECMAScript) Iterators
https://rbuckton.github.io/iterable-query
Apache License 2.0
69 stars 3 forks source link

Add minBy, maxBy #4

Closed DanielSWolf closed 5 years ago

DanielSWolf commented 5 years ago

I often want to determine the minimum or maximum element from a list by a certain criterium that can be derived from each list element. For instance, let's say I have a list of strings and want to determine the longest one.

Currently, min and max expect a comparison function that receives two entries, then returns a negative number, zero, or a positive number depending on whether the first element is less than, equal to, or greater than the second element, respectively.

So currently, I'd write my query as

Query.from(stringValues).max((a, b) => a.length - b.length);

This certainly works well for many situations, but it tends to get a bit verbose in many cases.

Many other libraries (such as Lodash) offer additional methods minBy and maxBy. They expect a callback that takes a single value and returns the corresponding comparison value.

If iterable-query supported these methods, I could write the example above as

Query.from(stringValues).maxBy(s => s.length);
rbuckton commented 5 years ago

Would it be better to have minBy/maxBy or a fn.propertyComparer function? The propertyComparer route would avoid over-cluttering the Query api:

// fn/common.ts
export function propertyComparer<T extends object, K extends keyof T>(key: K): (a: T, b: T) => number {
  return (a: T, b: T) => compare(a[key], b[key]);
}

// usage:
from(…).min(fn.propertyComparer("length"))
rbuckton commented 5 years ago

I went ahead with minBy/maxBy.

Fixed in 7a179038a1af7e1c649f0ff61549046b09b31a19 (iterable-query@1.0.0-pre.12, now on npm)

DanielSWolf commented 5 years ago

Wow, that was quick! Thanks!

rbuckton commented 5 years ago

Keep the suggestions coming. Once I improve the test coverage a bit I'll publish a 1.0.0 release.