Skip to main content

APIzation: Replication Package

[Q#47964368][A#47970130] How to skip successive elements in a java stream?

https://stackoverflow.com/q/47964368

I've been trying to incorporate more functional programming into what I do because of the of the side-effect-free nature of the code I write and its utility in concurrent code. I came across the need to filter out successive elements of a java stream and couldn't come up with a functional approach better than a plain old imperative approach. Say I have a program that logs its arguments and I want to filter out 2 successive elements. For example, -o anOption, -k aSecretKeyWhoseValueWeShouldNotLog, -a anotherOption. What I want in the log is -o anOption, -a anotherOption. I came up with several approaches, but none of them was as understandable as using a for loop that indexed past the stuff I needed to filter out. This seems like a fairly common thing to want to do. Is there a pattern, using java streams or anything else, that is commonly used for this kind of thing? Thanks, Here's what I ended up with.

Answer

https://stackoverflow.com/a/47970130

I'm not sure if this is any better than what you already have. Given that the input is a String[] and the (intermediate) output you want is also a String[] a simple-hearted translation to Java streams could be [-o, opt1, -a, opt2]

APIzation

static String[] filterOptionAndValue(String option, String args[]) {
    return IntStream.range(0, args.length)
            .filter(i -> i % 2 == 0)
            .mapToObj(i -> new AbstractMap.SimpleEntry<>(args[i], args[i + 1]))
            .filter(e -> !option.equals(e.getKey()))
            .flatMap(e -> Stream.of(e.getKey(), e.getValue()))
            .toArray(String[]::new);
}

public static void main(String... env) {

    String[] args = {"-o", "opt1", "-k", "secret", "-a", "opt2"};

    System.out.println(Arrays.toString(filterOptionAndValue("-k", args)));
}
package com.stackoverflow.api;

import java.util.AbstractMap;
import java.util.Arrays;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class Human47970130 {

  static String[] filterOptionAndValue(String option, String args[]) {
    return IntStream
      .range(0, args.length)
      .filter(i -> i % 2 == 0)
      .mapToObj(i -> new AbstractMap.SimpleEntry<>(args[i], args[i + 1]))
      .filter(e -> !option.equals(e.getKey()))
      .flatMap(e -> Stream.of(e.getKey(), e.getValue()))
      .toArray(String[]::new);
  }

  // String[] args = {"-o", "opt1", "-k", "secret", "-a", "opt2"};
  public static String printArguments(String[] args, String ignoredOption) {
    return Arrays.toString(filterOptionAndValue(ignoredOption, args));
  }
}

package com.stackoverflow.api;

import java.util.AbstractMap;
import java.util.Arrays;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * How to skip successive elements in a java stream?
 *
 * @author APIzator
 * @see <a href="https://stackoverflow.com/a/47970130">https://stackoverflow.com/a/47970130</a>
 */
public class APIzator47970130 {

  static String[] filterOptionAndValue(String option, String[] args) {
    return IntStream
      .range(0, args.length)
      .filter(i -> i % 2 == 0)
      .mapToObj(i -> new AbstractMap.SimpleEntry<>(args[i], args[i + 1]))
      .filter(e -> !option.equals(e.getKey()))
      .flatMap(e -> Stream.of(e.getKey(), e.getValue()))
      .toArray(String[]::new);
  }

  public static String skipElement(String[] args) {
    return Arrays.toString(filterOptionAndValue("-k", args));
  }
}