1

Given a Map<String, Either<Boolean, Integer>, what's the most straightforward way to convert it to a Map<String, Boolean> containing only the entries with boolean values?

Right now I have this:

Map<String, Boolean> boolMap = eitherMap
  .filter(entry -> entry._2.isLeft())
  .map((key, value) -> Tuple.of(key, value.getLeft())
;

This works, but seems unnecessarily wordy, and it seems like there should be some tighter, one-step, “flatmap that ” solution.

David Moles
  • 48,006
  • 27
  • 136
  • 235
  • I'm not familiar with Javaslang so I don't know the answer outright but it might be possible if Either is a 'biased' container. If it is unbiased I think your solution might be the simplest one – melston Feb 01 '17 at 18:23
  • @melston Can you clarify what you mean by 'biased container'? – David Moles Feb 01 '17 at 21:35
  • This is typically used of an Either-like container with one of two possible states. A biased variant is one where one state is a 'successful' state and the other is an error or failure state. In this case flatmapping works much like Option where calling flatmap on a None simply returns a None while calling flatmap on a Some(x) operates on the x and continues on. This approach is often called railway-oriented programming where a failure/none basically halts processing. So calling flatmap on a success processes the contained value while calling flatmap on failure simply returns the failure. – melston Feb 02 '17 at 22:47

1 Answers1

2

Disclaimer: I'm the creator of Javaslang

Here is a solution based on javaslang-2.1.0-alpha. We take advantage of the fact that Either is right-biased. Because we focus on the left values, we swap the Either. The flatMap iterates then over the Either, if it contains a boolean.

    import javaslang.collection.Map;
    import javaslang.control.Either;

    import static javaslang.API.*;

    public class Test {

        public static void main(String[] args) {

            Map<String, Either<Boolean, Integer>> map = Map(
                    "a", Left(true),
                    "b", Right(1),
                    "c", Left(false));

            Map<String, Boolean> result =
                    map.flatMap((s, e) -> e.swap().map(b -> Tuple(s, b)));

            // = HashMap((a, true), (c, false))
            println(result);

        }
    }

You achieve the same in javaslang-2.0.5 by using static factory methods like Tuple.of(s, b).

Daniel Dietrich
  • 2,262
  • 20
  • 25