Skip to content

Instantly share code, notes, and snippets.

@jbrains
Created November 27, 2016 21:02
Show Gist options
  • Save jbrains/b9244a1078fc72dc68da09d9adc35959 to your computer and use it in GitHub Desktop.
Save jbrains/b9244a1078fc72dc68da09d9adc35959 to your computer and use it in GitHub Desktop.
How do I extract map(trim), then filter(!empty) into a method while keeping the pipeline style?
new StreamTextCommands()
.streamCommandsFrom(new InputStreamReader(System.in))
.map(String::trim)
.filter((command) -> !command.isEmpty())
.map(commandText -> sellOneItemController.onBarcode(commandText))
.map(CommandResponse::render)
.forEach(System.out::println);
new StreamTextCommands()
.streamCommandsFrom(new InputStreamReader(System.in))
.magicApplyThatICantFind(MyClass::sanitize)
.map(commandText -> sellOneItemController.onBarcode(commandText))
.map(CommandResponse::render)
.forEach(System.out::println);
// ...
private static Stream<String> sanitize(Stream<String> uncleanCommands) {
return uncleanCommands
.map(String::trim)
.filter((command) -> !command.isEmpty());
}
sanitize(new StreamTextCommands()
.streamCommandsFrom(new InputStreamReader(System.in)))
.map(commandText -> sellOneItemController.onBarcode(commandText))
.map(CommandResponse::render)
.forEach(System.out::println);
// ...
private static Stream<String> sanitize(Stream<String> uncleanCommands) {
return uncleanCommands
.map(String::trim)
.filter((command) -> !command.isEmpty());
}
@nbardiuk
Copy link

new StreamTextCommands()
                .streamCommandsFrom(new InputStreamReader(System.in))
                .flatMap(MyClass::sanitize)
                .map(commandText -> sellOneItemController.onBarcode(commandText))
                .map(CommandResponse::render)
                .forEach(System.out::println);

private static Stream<String> sanitize(String uncleanCommand) {
     String clean = uncleanCommand.trim();   
     return clean.isEmpty() ? Stream.empty() : Stream.of(clean);
}

flatMap has a power to filter and map simultaneously, where empty stream represents removed value

@jbrains
Copy link
Author

jbrains commented Nov 27, 2016

Yes, @nbardiuk! I just arrived at almost the same answer myself. Thank you!

        new StreamTextCommands()
                .streamCommandsFrom(new InputStreamReader(System.in))
                .flatMap(PointOfSaleTerminal::sanitizeCommand)
                .map(commandText -> sellOneItemController.onBarcode(commandText))
                .map(CommandResponse::render)
                .forEach(System.out::println);

    private static Stream<String> sanitizeCommand(String uncleanCommand) {
        return Stream.of(uncleanCommand.trim()).filter(c -> !c.isEmpty());
    }

This illustrates the power of "making the types line up". Once I saw that flatMap turns an item into a Stream of (possibly other) things, I realized that I could apply "trim, the discard if empty" to each command. Even so, I preferred thinking of "map, then filter" as a composable transformation on Streams, but I'm willing to go with this, at least for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment