toss / es-toolkit

A modern JavaScript utility library that's 2-3 times faster and up to 97% smaller—a major upgrade to lodash.
https://es-toolkit.slash.page
Other
6.25k stars 263 forks source link

feat(flatMapDeep): Add flatMapDeep #464

Closed ssi02014 closed 1 week ago

ssi02014 commented 2 weeks ago

cloesd: #347

Add the flatMapDeep discussed in the issue above.

benchMark

스크린샷 2024-09-01 오후 2 01 18

This is more performant than utilizing lodash or the built-in array functions.

vercel[bot] commented 2 weeks ago

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
es-toolkit ✅ Ready (Inspect) Visit Preview 💬 Add feedback Sep 4, 2024 1:05am
codecov-commenter commented 2 weeks ago

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Project coverage is 99.78%. Comparing base (cb33fd2) to head (8ef84dc). Report is 1 commits behind head on main.

Additional details and impacted files [![Impacted file tree graph](https://app.codecov.io/gh/toss/es-toolkit/pull/464/graphs/tree.svg?width=650&height=150&src=pr&token=8N5S3AR3C7&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=toss)](https://app.codecov.io/gh/toss/es-toolkit/pull/464?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=toss) ```diff @@ Coverage Diff @@ ## main #464 +/- ## ======================================= Coverage 99.78% 99.78% ======================================= Files 177 178 +1 Lines 1380 1382 +2 Branches 366 366 ======================================= + Hits 1377 1379 +2 Misses 2 2 Partials 1 1 ```
ssi02014 commented 1 week ago

@raon0211 As a footnote to that function, the return type of flatMap is Array<FlatArray<U[], D>>, so specifying the type as infinity will not result in the intended type inference.

Therefore, we believe that flatMapDeep with the intended type inference is useful and serves the purpose of compatibility with lodash.

const arr = [1];

const newArr1 = flatMapDeep(arr, item => [[[item, item, [[item]]]]]); // number[]

newArr1.map(item => {
  item; // number
  item.toFixed(1); // ✅
});
const newArr2 = flatMap(arr, item => [[[item, item, [[item]]]]], Infinity);
// FlatArray<(number | number[][])[][][], 0 | 1 | -1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20>[]

newArr2.map(item => {
  item; // FlatArray<(number | number[][])[][][], 0 | 1 | 2 | 3 | 4 | -1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20>

  item.toFixed(1); // ❌
  (item as number).toFixed(1); // ✅ But this is not comfortable....
});


The issue with the Infinity type in typescript was previously mentioned by @raon0211 himself. https://github.com/toss/es-toolkit/issues/122#issuecomment-2214201240

Of course, we could work around it with something like flatMap(arr, 9999), but I think it's better to provide flatMapDeep than to do that.

const newArr3 = flatMap(arr, item => [[[item, item, [[item]]]]], 9999); 
// ..🤔 I don't think this is appropriate.

newArr3.map(item => {
  item; // number
  item.toFixed(1); // ✅
});


스크린샷 2024-09-04 오전 2 01 14


In fact, the performance difference between the two functions is not significant.

raon0211 commented 1 week ago

Yes, you're right. I accidentally forgot what we discussed 😅