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

Implement dropBefore and dropAfter #277

Open
delanym opened this issue Jun 15, 2024 · 0 comments
Open

Implement dropBefore and dropAfter #277

delanym opened this issue Jun 15, 2024 · 0 comments

Comments

@delanym
Copy link

delanym commented Jun 15, 2024

Requirement: Return the matching item from a stream (via short circuit) or the last item.

This requirement is deceptively simple. I have been unable to implement it using streams alone (I'm forced to start with a collection)

var aa = List.of("P", "Q", "R", "S", "T");
var bb = aa.stream()
    .filter(v -> Objects.equals(v, "S"))
    .reduce(aa.getLast(), (a, b) -> b);
System.out.printf("Result: %s%n", bb);

The result is "S". When the "S" is removed from the list the result is "T".

Proposal

A new dropBefore method (alternatively takeFrom or even takeAfterInclusive) could provide a stream having removed all items before but not including the matching item.

In above example, matching on "S" would result in Stream.of("S", "T") and no match would result in Stream.of("P", "Q", "R", "S", "T")

This would effectively be the same as dropWhile except without this characteristic If the predicate is true for all stream elements, an empty stream is returned.

This at least could provide an inclusive stream, and one could return "the matching item from a stream (via short circuit) or the FIRST item":

var aa = Stream.of("P", "Q", "R", "S", "T")
    .dropBefore(v -> Objects.equals(v, "S"))
    .reduce((a, b) -> a);

The result would be "S". When the "S" is removed from the list the result would be "P".

Then a new dropAfter method (alternatively takeUntil or takeBeforeInclusive) could provide a stream having removed all items after but not including the matching item.

var aa = Stream.of("P", "Q", "R", "S", "T")
    .dropAfter(v -> Objects.equals(v, "S"))
    .reduce((a, b) -> b);

The result would be "S". When the "S" is removed from the list the result would be "T".

The main distinction between these 2 new "before/after" methods and takeWhile and dropWhile is that the current item considered in the predicate is always part of the resulting stream whether the predicate is true or false.

This happens to be true for takeWhileInclusive. However, when the predicate is false the non-matching items are dropped (i.e. the last item, which I need for the requirement). If there was a dropWhileInclusive method the non-matching items would also be dropped (i.e. the first item).

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

1 participant