Reputation: 11921
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.
Upvotes: 18
Views: 77426
Reputation: 61979
One loop to either count or filter out the zeros cannot be avoided; however, the second loop can be avoided with the use of System.arraycopy()
.
This function will make a copy of an existing array into an array of different length, which means that before we use it our array must already be free from zeros. Therefore, in the first loop we cannot just count the zeros, we have to also filter them out. Here is how to actually do it:
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;
Upvotes: 25
Reputation: 21
public class RemoveZeros {
public static void main(String[] args) {
int arr[] = {1,0,0,1,0,0,1,0,0,0,0,1,2,0,5};
int n = arr.length;
for(int i=0; i<n; i++) {
if(arr[i]!=0) {
System.out.print(arr[i]+ " ");
}
}
}
}
Upvotes: 0
Reputation: 31
You can remove zeros in O(1) extra space. Instead of copying the elements into another array you can just return the size and print the same array:
public class RemoveZeros {
static int removeZeros(int[] a){
int j =0;
for(int i =0;i<a.length;i++) {
if(a[i] !=0) {
a[j] = a[i];
j++;
}
}
return j;
}
public static void main(String[] args) {
int[] a = new int[]{0, 5, 6, 0, 0, 2, 5};
int val = removeZeros(a);
for(int i =0;i<val;i++)
System.out.println(a[i]);
}
}
Upvotes: 2
Reputation: 11
Try the basic way:
public int[] convert(int[] data) {
int count =0;
for (int i =0; i< data.length; i++) {
if(data[i]==0)
count++;
}
int[] nonZero = new int[data.length-count];
int j =0;
for(int i = 0; i<data.length; i++) {
if(data[i]!=0) {
nonZero[j] = data[i];
j++;
}
}
return nonZero;
}
Upvotes: 1
Reputation: 89
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};
Upvotes: 5
Reputation: 1651
Does the programming language you use employ .map or .reduce functions, or is there an extension that allows you to do this?
In Swift, you can do this via .filter; observe
var orders = [0, 5, 6, 0, 0, 2, 5]
orders = orders.filter({ $0 != 0 })
print (orders)
This returns [5, 6, 2, 5]
, retaining your order
Upvotes: 2
Reputation: 36601
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()]);
Upvotes: 4
Reputation: 117587
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]
Upvotes: 13
Reputation: 112
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);
}
}
Upvotes: 3
Reputation: 4109
If you are allowed to user List instead of array, you can do actually nothing but create a new Iteratable interface and apply a method to it like google-collections Collections2.filter() does, you can check it out.
Upvotes: 1
Reputation: 14790
You can use a Vector
:
Vector vec = new Vector();
for (int i=0; i<array.length; i++){
if (array[i] != 0)
vec.add(array[i]);
}
vec.toArray()
(this isn't the precise syntax, but you get the idea..)
Upvotes: 1