4. Exercises

Refactor the operations of list comprehension.

Exercise 1

Exercise 1 — Java 11

Refactor the fixMe method and get rid of invoking the filter method that compares the element to null:

...
public final class Main {

    public static final class Node {

        ...
        public List<Node> getChildNodes() {
            ...
        }
        ...
    }

    private static List<Node> getNodes() {
        ...
    }

    private static void fixMe() {
        var list = getNodes().stream()
            .map(n -> n.getChildNodes().stream().findFirst().orElse(null))
            // The next statement is equivalent to '.filter(Objects::nonNull)'
            .filter(n -> n != null)
            .collect(Collectors.toList());
        ...
    }
    ...

Run

Exercise 1 — C# 8

Refactor the FixMe method and get rid of invoking the Where method that compares the element to null:

...
public sealed class Program
{
    public sealed class Node
    {
        ...
        public IEnumerable<Node> ChildNodes { get; }
        ...
    }

    private static IEnumerable<Node> Nodes { get; } = ...;

    private static void FixMe()
    {
        var list = Nodes
            // Defers disposition of 'null' when 'ChildNodes' is empty
            .Select(n => n.ChildNodes.FirstOrDefault())
            .Where(n => n is {});
        ...

Run

Exercise 1 — Swift 5

Refactor the fixMe function and get rid of invoking the filter method that compares the element to nil:

public class Node : CustomStringConvertible {
  ...
  public let childNodes: [Node]
  ...
  public var description: String { ... }
}

let nodes = [ ... ]

func fixMe() {
  let list = nodes.map { $0.childNodes.first }
    .filter { $0 != nil }
  ...
}

Run

Exercise 1 — Kotlin 1.3

Refactor the fixMe function and get rid of invoking the filterNonNull method:

public class Node ... {
    ...
    public val childNodes = ...
    ...
    public override fun toString(): String {
        ...
    }
}

val nodes = arrayOf(...)

fun fixMe() {
    val list = nodes.map { it.childNodes.firstOrNull() }
        .filterNotNull()
    ...
}

Run

Exercise 1 — Example Answers

Language URL
Java 11 Here
C# 8 Here
Swift 5 Here
Kotlin 1.3 Here

Exercise 2

Exercise 2 — Java 11

Refactor the fixMe method and get rid of invoking the filter method that compares the element to null:

...
import static java.util.Map.entry;

public final class Main {

    private static final Map<String, Runnable> COMMAND_MAP = Map.ofEntries(
            entry("help", () -> printHelp()),
            entry("quit", () -> exitProgram()),
            entry("shutdown", () -> shutdownSystem()));

    ...
    private static List<String> getCommandList() {
        return List.of("help", "reboot", "shutdown");
    }

    private static void fixMe() {
        var list = getCommandList().stream()
            // Defers disposition of 'null' when 'Map#get(Object)' returns
            // 'null'
            .map(COMMAND_MAP::get)
            // The next statement is equivalent to '.filter(Objects::nonNull)'
            .filter(r -> r != null)
            .collect(Collectors.toList());
        ...
    }
    ...

Run

Exercise 2 — C# 8

Refactor the FixMe method and get rid of invoking the Where method that compares the element to null:

public static class Program
{
    private static readonly ImmutableDictionary<string, Action> CommandMap
        = new Dictionary<string, Action>()
        {
            ["help"] = () => PrintHelp(),
            ["quit"] = () => ExitProgram(),
            ["shutdown"] = () => ShutdownSystem(),
        }.ToImmutableDictionary();

    ...
    private static IEnumerable<string> CommandList { get; }
        = new[] { "help", "reboot", "shutdown" };

    private static void FixMe()
    {
        var list = CommandList
            // Converts the element to 'null' when 'TryGetValue(TKey, out TVaue)'
            // returns 'false'
            .Select(n => CommandMap.TryGetValue(n, out var action)
                ? action
                : null)
            .Where(a => a is {});
        ...
    }
    ...

Run

Exercise 2 — Swift 5

Refactor the fixMe function and get rid of invoking the filter method that compares the element to nil:

...

let commandMap = [
  "help": { printHelp() },
  "quit": { exitProgram() },
  "shutdown": { shutdownSystem() }]

func getCommandList() -> [String] {
  return ["help", "reboot", "shutdown"]
}

func fixMe() {
  let list = getCommandList().map { commandMap[$0] }
    .filter { $0 != nil }
  ...
}

Run

Exercise 2 — Kotlin 1.3

Refactor the fixMe function and get rid of invoking the filterNonNull method:

val commandMap = mapOf(
    "help" to { printHelp() },
    "quit" to { exitProgram() },
    "shutdown" to { shutdownSystem() })

...

fun getCommandList(): List<String> {
    return listOf("help", "reboot", "shutdown")
}

fun fixMe() {
    val list = getCommandList()
        .map { commandMap.get(it) }
        .filterNotNull()
    ...
}

Run

Exercise 2 — Example Answers

Language URL
Java 11 Here
C# 8 Here
Swift 5 Here
Kotlin 1.3 Here