Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add match and matchAll #438

Open
LandonSchropp opened this issue Dec 11, 2023 · 7 comments
Open

Add match and matchAll #438

LandonSchropp opened this issue Dec 11, 2023 · 7 comments

Comments

@LandonSchropp
Copy link
Contributor

It would be nice to have these two String methods in Remeda for a couple of reasons:

  • They can be used in a "data-last" version, which is helpful in pipes and chains.
  • The matchAll method returns IterableIterator<RegExpMatchArray>, which isn't a useful data structure. It's very common to write [...input.matchAll(regex)], which doesn't lend itself well to pipes. A Remeda matchAll function could return a normal array.

For reference, Lodash doesn't implement either function. Ramda implements match, but not matchAll.

@LandonSchropp
Copy link
Contributor Author

If you like this idea, I'm happy to open a PR. 🙂

@eranhirsch
Copy link
Collaborator

This would be a welcome addition. My concern is spreading the iterator. It returns an iterator because there might be performance concerns with parsing or running the regex on a document when it is massive. The iterator approach allows JS to run it lazily. Because the primary purpose here is to make it more comfortable to work within a pipe, we should look into the lazy (piped) implementation in Remeda to see if we can pass along the benefits of the returned iterator via the pipe.

const x = pipe(
  data,
  matchAll(/foo(.*)/ug),
  // We expect results from matchAll to be "pulled" only when needed, until the first result is found.
  map((result) => something(result)),
  filter((result) => somethingelse(result),
  first(),
);

Check out functions like "map" and "filter" to see how lazy evaluation in Remeda work.

@LandonSchropp
Copy link
Contributor Author

LandonSchropp commented Dec 11, 2023

@eranhirsch That makes sense. When I was digging through the issues, I noticed #74 and #213. Is the long-term plan to migrate everything over to Iterator? If so, that'd be pretty cool and would make that return type here really convenient for pipes.

e.g.

export function filter<T, S extends T>(
  array: Iterable<T>,
  fn: (value: T) => value is S
): Array<S>;

For now, I suppose I could always do this to simplify piping. 🙂

const x = pipe(
  data,
  matchAll(/foo(.*)/ug),
  Array.from,
  ...
);

@eranhirsch
Copy link
Collaborator

At the bare minimum, we can add an "iterate" function that takes an Iterator and answers our internal lazy evaluation API so that iterators can be used in pipes without needing to add the functionality specifically for each browser/ECMAScript API that returns an iterator.

@somnicattus
Copy link
Contributor

Hello.

I published remeda-compatible npm package rotery, which expands remeda with Iterators and AsyncIterators support.

https://github.com/somnicattus/rotery

@LandonSchropp
Copy link
Contributor Author

@somnicattus Just out of curiosity, why not contribute to Remeda instead? From my perspective, they've been open and receptive to PRs. 🙂

@somnicattus
Copy link
Contributor

somnicattus commented Apr 6, 2024

@LandonSchropp Actually, I have no idea how the iterator/asyncIterator features should be merged into remeda.

Not many people need iterator/asyncIterator, so it can be even annoying because these features have the same names as some array utilities.
So, please feel free to propose methods for merging the iterator/asyncIterator feature and make PRs.

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

No branches or pull requests

3 participants