Create a stream of custom alternating numbers

Zombies :

How can I make an IntStream that starts in the middle of a given sequential range, and then streams the next numbers starting in the middle and alternating to the left and right. For example, for a given sequential range of numbers 1 2 3 4 5, the custom sequence would be 3 2 4 1 5 or 3 4 2 5 1 depending whether you start with left or right first.

I basically am trying to iterate through an array starting from the middle and going outward evenly (not going to the left or right fully first).

I have tried this using just for loops but the code is messy and I think it would be much better to just line up a collection or stream of numbers instead of checking for it on the fly (because of all the index out of bounds exceptions that have to be checked for). Here is the original code that I think would be much better as a pre computed stream of ints:

        int middle = myArray.length / 2;
        Object value = myArray[middle]; //have to reference middle since the for loop won't
        //do operation on value
        for (int offset = 1; true; offset++) {
            int nextRight = middle + offset;
            int nextLeft = middle - offset;
            if (nextRight < myArray.length) { // Have to guard against exception, but can't catch exception ahead of time because left or null may not be empty.
                Object value = myArray[nextRight];
                //do operation on value
            }
            if (nextLeft >= 0) {
                Object value = myArray[nextRight];
                //do operation on value
            }
            if (nextRight >= myArray.length) {
                break; //exit logic
            }
            if (nextLeft < 0) {
                break; //exit logic
            }
        }
PaperMonoid :

This solution uses iterators and streams:

boolean toLeft = false;
int size = 5;

int half = size % 2 == 0 ? size / 2 : size / 2 + 1;
IntStream inferiorStream = IntStream.iterate (half, x -> x - 1);
IntStream superiorStream = IntStream.iterate (half, x -> x + 1);

OfInt a = toLeft 
          ? inferiorStream.iterator () 
          : superiorStream.iterator ();
OfInt b = toLeft 
          ? superiorStream.skip (1).iterator () 
          : inferiorStream.skip (1).iterator ();

IntStream stream = Stream.generate (() -> IntStream.concat (
    a.hasNext () ? IntStream.of (a.nextInt ()) : IntStream.empty (),
    b.hasNext () ? IntStream.of (b.nextInt ()) : IntStream.empty ()))
    .flatMapToInt (Function.identity ())
    .limit (size);

stream.forEach (System.out :: println);

Output (toLeft = true):

3
4
2
5
1

Output (toLeft = false):

3
2
4
1
5

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=435637&siteId=1