Remove all zeros from array
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 int
s
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);
}
}
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, 2022Comments
-
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 over 12 yearsBut then you end with an
Integer[]
and not anint[]
-
Mike Nakis over 12 years@Robin No you don't. How is that?
-
Hidde over 12 yearsPerformance 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 over 12 yearsI prefer using an ArrayList, since it uses generics.
-
Mike Nakis over 12 yearsHidde, I amended my answer. I think this solution is the best.
-
Hidde over 12 yearsWon't you end up with [0, 5, 6, 0] in your example?
-
Robin over 12 years@MikeNakis since you cannot have a
List<int>
. So you would have to manually convert the resultingInteger[]
(which you get fromList#toArray
) to anint[]
-
Hidde over 12 yearsI'm sorry, I have read it wrongly. I didn't see the value of array[i] was put into array[j].
-
Hidde over 12 yearsKind of a duplicate of Mike's answer.
-
Robin over 12 yearsYups, although it wasn't present in his original one and that was the only one I saw before starting with this answer
-
Robin over 12 years@MartijnCourteaux
Vector
can make use of generics as well. There are far better reasons to opt for anArrayList
instead of aVector
(see for example this question on SO) -
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
int
s. I will correct my answer, thank you. -
Hidde over 12 yearsIt 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 over 12 yearsYes, 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 ofInteger
s, not an array ofint
s. -
Manish Giri about 9 yearsI understood most of this answer, except in the line
numbers = list.toArray(new Integer[0]);
, what doesnew Integer[0]
help in? I understand that it initializes a new Integer array with size 0, but how does it help? -
GriffinG almost 7 yearsApache 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 over 6 yearsPerhaps the programming language you use has a Underscore library or Lo-Dash
-
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.