Remove all zeros from array

57,236

Solution 1

This is one of those rare cases where it is easier to show it in code than to explain in plain English:

int targetIndex = 0;
for( int sourceIndex = 0;  sourceIndex < array.length;  sourceIndex++ )
{
    if( array[sourceIndex] != 0 )
        array[targetIndex++] = array[sourceIndex];
}
int[] newArray = new int[targetIndex];
System.arraycopy( array, 0, newArray, 0, targetIndex );
return newArray;

Solution 2

How about this:

Integer[] numbers = {1, 3, 6, 0, 4, 0, 3};
List<Integer> list = new ArrayList<Integer>(Arrays.asList(numbers));
list.removeAll(Arrays.asList(Integer.valueOf(0)));
numbers = list.toArray(new Integer[list.size()]);
System.out.println(Arrays.toString(numbers));

OUTPUT:

[1, 3, 6, 4, 3]

Solution 3

With Java 8 you can make a stream out of the array, apply .filter() and then convert it back into an array :

int[] array = {0, 5, 6, 0, 0, 2, 5};

int[] filteredArray = Arrays.stream(array).filter(num -> num != 0).toArray();    

// filteredArray = {5, 6, 2, 5};

Solution 4

You can achieve this with one loop only. Whether this is better or more clear is a matter of personal taste I am afraid.

int[] array = {0, 5, 6, 0, 0, 2, 5};
int[] temp = new int[array.length];
int numberOfZeros = 0;
for (int i=0; i<array.length; i++){
  if (array[i] != 0){
    temp[i-numberOfZeros] = array[i];
  } else {
    numberOfZeros++;
  }
}
int[] result = new int[temp.length-numberOfZeros];
System.arraycopy(temp, 0, result, 0, result.length);

Another option would be to use a List implementation like ArrayList from which you can just remove elements, but then you will have to work with Integer instances and not with ints

List<Integer> originalList = ....;
Iterator<Integer> iterator = originalList.iterator();
while ( iterator.hasNext() ) {
  Integer next = iterator.next();
  if ( next == 0 ){
    iterator.remove();
  }
}
//convert to array if needed
Integer[] result = originalList.toArray( new Integer[originalList.size()]);

Solution 5

This example uses Apache Commons library , I hope this will be useful to you

import org.apache.commons.lang.ArrayUtils;

public class Test {
    public static void main(String args[]) {
        int[] array = {0, 5, 6, 0, 0, 2, 5};

        // this loop is to remove all zeros
        while(ArrayUtils.contains(array, 0))
            array = ArrayUtils.removeElement(array, 0);

        // this loop will print the array elemnents
        for(int i : array)
            System.out.println(i);

    }
}
Share:
57,236
Hidde
Author by

Hidde

Programmer and mathematician. Problem solver. Lover of clean code, coffee, cycling, running and Italian food. Kotlin, Java, Spock (Groovy), PHP, Angular, MySQL, ... #SOreadytohelp

Updated on July 22, 2022

Comments

  • Hidde
    Hidde almost 2 years

    I have an array:

    [0, 5, 6, 0, 0, 2, 5]
    

    I would like to remove all zeros from it, so that this returns (keeping the same order):

    [5, 6, 2, 5]
    

    Is there any easier way to remove all zeros than the following?

    int[] array = {0, 5, 6, 0, 0, 2, 5};
            int len = 0;
            for (int i=0; i<array.length; i++){
                if (array[i] != 0)
                    len++;
            }
            int [] newArray = new int[len];
            for (int i=0, j=0; i<array.length; i++){
                if (array[i] != 0) {
                    newArray[j] = array[i];
                    j++;
                }
            }
    

    I haven't been able to find any method in the Arrays class, and Google/SO searches didn't give me any good answers.

  • Robin
    Robin over 12 years
    But then you end with an Integer[] and not an int[]
  • Mike Nakis
    Mike Nakis over 12 years
    @Robin No you don't. How is that?
  • Hidde
    Hidde over 12 years
    Performance is not really a problem here, I was looking for shorter ways to write the above. I like ArrayLists, but hoped there would be a shorter way just using arrays.
  • Martijn Courteaux
    Martijn Courteaux over 12 years
    I prefer using an ArrayList, since it uses generics.
  • Mike Nakis
    Mike Nakis over 12 years
    Hidde, I amended my answer. I think this solution is the best.
  • Hidde
    Hidde over 12 years
    Won't you end up with [0, 5, 6, 0] in your example?
  • Robin
    Robin over 12 years
    @MikeNakis since you cannot have a List<int>. So you would have to manually convert the resulting Integer[] (which you get from List#toArray) to an int[]
  • Hidde
    Hidde over 12 years
    I'm sorry, I have read it wrongly. I didn't see the value of array[i] was put into array[j].
  • Hidde
    Hidde over 12 years
    Kind of a duplicate of Mike's answer.
  • Robin
    Robin over 12 years
    Yups, although it wasn't present in his original one and that was the only one I saw before starting with this answer
  • Robin
    Robin over 12 years
    @MartijnCourteaux Vector can make use of generics as well. There are far better reasons to opt for an ArrayList instead of a Vector (see for example this question on SO)
  • Mike Nakis
    Mike Nakis over 12 years
    @Robin I took a look at the documentation, and it appears that you are right. It has been a long time since I last wrote a line of code in Java, and I have been using C# since then, in which it is possible to have an array-list of primitive ints. I will correct my answer, thank you.
  • Hidde
    Hidde over 12 years
    It is true a Integer[] will result from an list.toArray(), however you can harmlessly cast an Integer to int (in Java), to there is no problem there.
  • Mike Nakis
    Mike Nakis over 12 years
    Yes, but then you will need another int array allocation, and another loop in order to perform these casts, because toArray() will give you an array of Integers, not an array of ints.
  • Manish Giri
    Manish Giri about 9 years
    I understood most of this answer, except in the line numbers = list.toArray(new Integer[0]);, what does new Integer[0] help in? I understand that it initializes a new Integer array with size 0, but how does it help?
  • GriffinG
    GriffinG almost 7 years
    Apache commons lang 3.5 now contains removeAllOccurences(T[] array, T element) which does exactly what the OP wants and what you suggested, but without having to loop.
  • zardon
    zardon over 6 years
    Perhaps the programming language you use has a Underscore library or Lo-Dash
  • Nikita Kobtsev
    Nikita Kobtsev over 2 years
    @ManishGiri sorry to reply to a comment from six years ago, you probably already figured it out. Perhaps it will be useful to someone else. Creating a zero-sized array allows the toArray() method to find the type of the returned array using the reflection. You have to do this in order to explicitly determine the type of the returned array at compile time. By the way such array creation is pretty well optimized in the latest versions of JVM and works fast.