Skip to content

fix(compat/maxBy, compat/minBy): restore lodash compatible comparison behavior - #1893

Merged
raon0211 merged 3 commits into
toss:mainfrom
Antoliny0919:fix-1890
Jul 18, 2026
Merged

raon0211 merged 3 commits into
toss:mainfrom
Antoliny0919:fix-1890

Conversation

@Antoliny0919

Copy link
Copy Markdown
Contributor

Summary

Closes: #1890

regression in e319b3b

This change fixes the issue where comparisons weren't being performed correctly for string values.
Additionally, it updates the behavior so that NaN values are skipped when present during comparison, and undefined is returned when the array contains only NaN values.
These were additional compatibility issues.

Reproduce

e911de8

console.log(lodash.maxBy([{ v: 'a' }, { v: 'b' }], item => item.v)); // { v: 'b' }
console.log(maxBy([{ v: 'a' }, { v: 'b' }], item => item.v)); // { v: 'a' }
console.log(lodash.minBy([{ v: 'b' }, { v: 'a' }], item => item.v)); // { v: 'a' }
console.log(minBy([{ v: 'b' }, { v: 'a' }], item => item.v)); // { v: 'b' }

aeaad75

console.log(lodash.maxBy([3, NaN, 1, 2], x => x)); // 3
console.log(maxBy([3, NaN, 1, 2], x => x)); // NaN
console.log(lodash.minBy([3, NaN, 1, 2], x => x)); // 1
console.log(minBy([3, NaN, 1, 2], x => x)); // NaN

console.log(lodash.maxBy([NaN, NaN], x => x)); // undefined
console.log(maxBy([NaN, NaN], x => x)); // MaN
console.log(lodash.minBy([NaN, NaN], x => x)); // undefined
console.log(minBy([NaN, NaN], x => x)); // NaN

@vercel

vercel Bot commented Jul 17, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
es-toolkit Ready Ready Preview, Comment Jul 17, 2026 5:14am

Request Review

@Antoliny0919

Copy link
Copy Markdown
Contributor Author

35d57a4

minBy-default

@raon0211 raon0211 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@raon0211
raon0211 merged commit 914c6d8 into toss:main Jul 18, 2026
12 checks passed
gwennlbh pushed a commit to cigaleapp/cigale that referenced this pull request Aug 3, 2026
##### [v1.50.0](https://github.com/toss/es-toolkit/blob/HEAD/CHANGELOG.md#Version-v1500)

Released on July 24th, 2026.

- Added the `es-toolkit/types` entrypoint: a declaration-only module of compile-time
  type utilities TypeScript lacks natively — `ValueOf`, `Simplify`, `Writable`,
  `NonEmptyArray`, `DeepPartial`, and `DeepReadonly`. (\[[#1818](toss/es-toolkit#1818)])
- Added `flow` to `es-toolkit/fp`, a reusable data-last composition built on `pipe`. (\[[#1812](toss/es-toolkit#1812)])

The following bring `es-toolkit/compat` closer to Lodash. Behavior for the affected
edge cases now matches Lodash, so results may differ if you relied on the previous output.

- Fixed `compat/intersectionBy` to dedupe a single array (including by the iteratee)
  and to keep results consistent with Lodash. (\[[#1935](toss/es-toolkit#1935)])

- Fixed `compat/findIndex` and `compat/findLastIndex` to coerce a `NaN` `fromIndex`
  to `0` and to convert `fromIndex` to an integer. (\[[#1828](toss/es-toolkit#1828)], \[[#1834](toss/es-toolkit#1834)], \[[#1938](toss/es-toolkit#1938)])

- Fixed `compat/lastIndexOf` to coerce `fromIndex` like Lodash. (\[[#1832](toss/es-toolkit#1832)])

- Fixed `compat/every` to treat a falsy, non-nullish `doesMatch` as a `_.property`
  shorthand instead of identity. (\[[#1940](toss/es-toolkit#1940)])

- Fixed `compat/nth` to support string inputs. (\[[#1833](toss/es-toolkit#1833)])

- Fixed `compat/inRange` to not throw on a lone negative bound. (\[[#1835](toss/es-toolkit#1835)])

- Fixed `compat/toArray` to convert `Set`s to arrays like Lodash. (\[[#1840](toss/es-toolkit#1840)])

- Fixed `compat/values` to treat sparse array holes as `undefined`. (\[[#1894](toss/es-toolkit#1894)])

- Fixed `compat/maxBy` and `compat/minBy` to restore Lodash-compatible comparison. (\[[#1893](toss/es-toolkit#1893)])

- Fixed `compat/includes` to exclude the `length` property when matching array-like values. (\[[#1886](toss/es-toolkit#1886)])

- Fixed the case functions to split ordinal numbers like Lodash, and to count string
  size and padding by code points for multi-byte characters. (\[[#1836](toss/es-toolkit#1836)], \[[#1852](toss/es-toolkit#1852)], \[[#1853](toss/es-toolkit#1853)])

- Fixed `compat/unset` to not treat an own literal dotted key as a deep path. (\[[#1808](toss/es-toolkit#1808)])

- Moved `compat/flattenDepth`'s flattening logic out of `flatten`. (\[[#1847](toss/es-toolkit#1847)])

- Restored the standalone `eq` and `templateSettings` entry points. (\[[#1895](toss/es-toolkit#1895)])

- Fixed `deburr` to remove all combining diacritical marks, matching Lodash. (\[[#1807](toss/es-toolkit#1807)])

- Fixed `partition` to accept any predicate return value, like `Array.prototype.filter`. (\[[#1937](toss/es-toolkit#1937)])

- Fixed `has` and `hasIn` to prioritize nullish literal keys over paths. (\[[#1810](toss/es-toolkit#1810)])

- Fixed `invokeMap` to normalize a string path via `toPath` for `this` binding. (\[[#1814](toss/es-toolkit#1814)])

- Fixed `isDeepKey` to detect deep keys with stricter patterns. (\[[#1621](toss/es-toolkit#1621)])

- Fixed `unzipWith` to return an empty array instead of throwing on empty input. (\[[#1816](toss/es-toolkit#1816)])

- Improved documentation, JSDoc accuracy, and internal refactoring across `compat`
  and `fp`. (\[[#1817](toss/es-toolkit#1817)], \[[#1820](toss/es-toolkit#1820)], \[[#1822](toss/es-toolkit#1822)], \[[#1823](toss/es-toolkit#1823)], \[[#1825](toss/es-toolkit#1825)], \[[#1829](toss/es-toolkit#1829)], \[[#1830](toss/es-toolkit#1830)], \[[#1842](toss/es-toolkit#1842)],
  \[[#1845](toss/es-toolkit#1845)], \[[#1851](toss/es-toolkit#1851)], \[[#1858](toss/es-toolkit#1858)], \[[#1867](toss/es-toolkit#1867)], \[[#1879](toss/es-toolkit#1879)])

We sincerely thank [@Antoliny0919](https://github.com/Antoliny0919), [@raon0211](https://github.com/raon0211), [@dayongkr](https://github.com/dayongkr), [@spokodev](https://github.com/spokodev), [@sarathfrancis90](https://github.com/sarathfrancis90),
[@mayur-shenoy](https://github.com/mayur-shenoy), [@mahirhir](https://github.com/mahirhir), [@kojesung](https://github.com/kojesung), [@Hprogram](https://github.com/Hprogram), [@BangDori](https://github.com/BangDori), and everyone else who
contributed. We appreciate your great efforts!

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

This branch was successfully deployed

1 active deployment
Preview — 35d57a44 Deployed Jul 17, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

maxBy/minBy return the first element for non-numeric values (regression in 1.48.0)

2 participants