How to copy an int array only with non leading zero

Viewed 102

I have an int array which has few leading zeros. I want to copy this array into another int array without leading zeros.

this is the code I wrote. but this code copies only non zero ints.

Original array:

     int samples[]= {0, 0, 0, 0, 0, 40, 0, 2532, 17, -2300, -17, -4000, 0, 2000, 1048, -420, 33, 15, -32, 2030, 3223, 0, 0};

New array should be :

    int noleadingzeroarray[] = {40,0,2532, 17, -2300, -17, -4000, 0, 2000, 1048, -420, 33, 15, -32, 2030, 3223, 0, 0};

Code:

 public static void trimSilenceFromBeginning(){

    int leadingZeros = 0;
    int samples[]= {0, 0, 0, 0, 0, 40, 0, 2532, 17, -2300, -17, -4000, 0, 2000, 1048, -420, 33, 15, -32, 2030, 3223, 0, 0};
    int noleadingzeroarray[]= new int[samples.length];
    int zeroscounter= 0;
    boolean nonzeroencountered  = false;

    if(samples[leadingZeros] == 0) {
        leadingZeros++;

    }

    for(int j= 0; j< samples.length; j++){

        if(samples[j]!=0 ) {
                noleadingzeroarray[zeroscounter] = samples[j];
                zeroscounter++;               
        }
    }
    System.out.println(Arrays.toString(noleadingzeroarray));
  }
} 
5 Answers

Arrays.copyOfRange to just use arrays without other element involved (Collections, etc).

Copies the specified range of the specified array into a new array. The initial index of the range (from) must lie between zero and original.length, inclusive.

3 lines:

int start;
for (start = 0; start < samples.length && samples[start] == 0; start++) {}
int[] noleadingzeroarray = Arrays.copyOfRange(samples, start, samples.length);
  • If no zero is found in samples, start will be 0 - the entire array will be shallow copied
  • If leading zeroes are found, start will be assigned the starting index after the last zero's position. - a subarray will be shallow copied

Don't panic with the shallow copy term, they're ints (primitives). No problem.

public static void trimSilenceFromBeginning() {
    int samples[]= { 0, 0, 0, 0, 0, 40, 0, 2532, 17, -2300, 
                     -17, -4000, 0, 2000, 1048, -420, 33,
                     15, -32, 2030, 3223, 0, 0};

    int leadingZeros = 0;
    while (leadingZeros < samples.length && samples[leadingZeros] == 0) {
        leadingZeros++;
    }
    int[] noleadingzeroarray = Arrays.copyOfRange(samples, leadingZeroes, samples.length);

    System.out.println(Arrays.toString(noleadingzeroarray));
  }
} 

Try it like this using streams. This will drop all values that are 0. Once a nonzero is detected, the rest of the arrays is streamed.

int[] samples = { 0, 0, 0, 0, 0, 40, 0, 2532, 17, -2300, -17,
        -4000, 0, 2000, 1048, -420, 33, 15, -32, 2030, 3223,
        0, 0 };


int[] result = Arrays.stream(samples)
        .dropWhile(a ->a == 0)
        .toArray();
System.out.println(Arrays.toString(result));

Prints

[40, 0, 2532, 17, -2300, -17, -4000, 0, 2000, 1048, -420, 33, 15, -32, 2030, 322
3, 0, 0]

And here is a non stream solution using a while loop and range copy.

int i = 0;
while (i < samples.length) {
    if (samples[i] != 0) {
        samples = Arrays.copyOfRange(samples, i, samples.length);
        break;
    }
    i++;
}

change first if statement to

while(samples[leadingZeros] == 0) {
    leadingZeros++;

}

An example of applying Stream API to this task:

int[] samples = { 0, 0, 0, 0, 0, 40, 0, 2532, 17, -2300, 
                 -17, -4000, 0, 2000, 1048, -420, 33,
                 15, -32, 2030, 3223, 0, 0};

boolean[] nonZero = {false}; // or AtomicBoolean may be used instead

int[] noZeros = Arrays.stream(samples)
                      .filter(x -> nonZero[0] |= x != 0) // false until first non-0 detected
                      .toArray();
System.out.println(Arrays.toString(noZeros));

Output:

[40, 0, 2532, 17, -2300, -17, -4000, 0, 2000, 1048, -420, 33, 15, -32, 2030, 3223, 0, 0]
Related