How to remove a specific element from an Array? [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Removing an element from an Array (Java)
How to remove specific String array value for example
String[] str_array = {"item1","item2","item3"};
i want to remove "item2" from str_array pls help me i want output like
String[] str_array = {"item1","item3"};

I would do it as follows:
String[] str_array = {"item1","item2","item3"};
List<String> list = new ArrayList<String>(Arrays.asList(str_array));
list.remove("item2");
str_array = list.toArray(new String[0]);

If you must use arrays, System.arraycopy is the most efficient, scalable solution. However, if you must remove one element from an array several times, you should use an implementation of List rather than an array.
The following utilizes System.arraycopy in order to achieve the desired effect.
public static Object[] remove(Object[] array, Object element) {
if (array.length > 0) {
int index = -1;
for (int i = 0; i < array.length; i++) {
if (array[i].equals(element)) {
index = i;
break;
}
}
if (index >= 0) {
Object[] copy = (Object[]) Array.newInstance(array.getClass()
.getComponentType(), array.length - 1);
if (copy.length > 0) {
System.arraycopy(array, 0, copy, 0, index);
System.arraycopy(array, index + 1, copy, index, copy.length - index);
}
return copy;
}
}
return array;
}
Also, you can increase the method's efficiency if you know that your array consists of only Comparable objects. You can use Arrays.sort to sort them before passing them through the remove method, modified to use Arrays.binarySearch to find index rather than a for loop, raising that portion of the method's efficiency from O(n) to O(nlogn).

Other Option is to copy array to other array accept than remove item.
public static String[] removeItemFromArray(String[] input, String item) {
if (input == null) {
return null;
} else if (input.length <= 0) {
return input;
} else {
String[] output = new String[input.length - 1];
int count = 0;
for (String i : input) {
if (!i.equals(item)) {
output[count++] = i;
}
}
return output;
}
}

Related

How to do an empty array

I have this question here
Once a player has drawn the top card from the deck, they must discard it.
Given a deck of cards, return a new deck containing all the cards except the first from the original deck.
Note: The new array returned is one element shorter than the original, except when the deck has no cards. Then the array returned must be empty.
So basically I have to make a new array thats the same as the old array minus the card at index 0. The issue im having is when I have to put an empty array and IntelliJ keeps throwing a NegativeArraySizeException.
public String[] discardTopCard(String[] remainingDeck) {
String[] newHand = new String[remainingDeck.length - 1];
String[] emptyArray = new String[] {};
int k = 0;
if (remainingDeck.length == 0 || remainingDeck.length == 1) {
return emptyArray;
}
for (int i = 1; i < remainingDeck.length; i++) {
newHand[k] = remainingDeck[i];
k++;
}
return newHand;
}
this is my current code.
I've also tried this and just setting it to null
public String[] discardTopCard(String[] remainingDeck) {
String[] newHand = new String[remainingDeck.length - 1];
int k = 0;
if (remainingDeck.length == 0 || remainingDeck.length == 1) {
return remainingDeck;
}
for (int i = 1; i < remainingDeck.length; i++) {
newHand[k] = remainingDeck[i];
k++;
}
return newHand;
}
If you want to work with a new array that is only part of an existing on, I would recommend to use an existing method: java.util.Arrays.copyOfRange
Example:
private static final String[] EMPTY_STRING_ARRAY = new String[0];
public String[] discardTopCard(String[] remainingDeck) {
int length = remainingDeck.length;
if (length < 2) {
return EMPTY_STRING_ARRAY;
}
return Arrays.copyOfRange(remainingDeck, 1, length);
}
I declared the empty string array as constant outside the method, because it is immutable and it's not necessary to create more than one instance in the whole program.
Both cases, empty input array and input array of lenght 1 will have the same result: an empty array.
Also note that usage of length in the copyOfRange method is OK because there it acts as "to"-index and not as number of elements to copy.
Or, even simpler:
public String[] discardTopCard(String[] deck) {
if (deck.length > 1)
deck = Arrays.copyOfRange(deck, 1, deck.length);
return deck;
}
How about this?
public String[] discardTopCard(String[] deck) {
if (deck.length == 0) {
return deck;
}
String[] smallerDeck = new String[deck.length - 1];
for (int i = 0; i < smallerDeck.length; i++) {
smallerDeck[i] = deck[i];
}
return smallerDeck;
}

Java: Remove an item from existing String Array

I've scoured a couple of the SOF threads but can't seem to find the answer I'm looking for. Most of them provide an answer with code that's beyond the scope of what I have learned thus far.
I've tried quite a few different things and can't get this to work the way I need it to.
The program is supposed to take the given array, read it, find the given toRemove item, and re-print the array without the toRemove item.
I believe my issue is within the removeFromArray method
public static void main(String[] args)
{
String[] test = {"this", "is", "the", "example", "of", "the", "call"};
String[] result = removeFromArray(test, "the");
System.out.println(Arrays.toString(result));
}
public static String[] removeFromArray(String[] arr, String toRemove)
{
int newLength = 0;
for(int i = 0; i < arr.length; i++)
{
if(arr[i].contains(toRemove))
{
newLength++;
}
}
String[] result = new String[arr.length-newLength];
for(int i = 0; i < (result.length); i++)
{
if(arr[i].contains(toRemove))
{
}
else
{
result[i] = arr[i];
}
}
return result;
}
This is an assignment in my java class and we have not learned Lists (one of the answers I stumbled upon in my googling) yet so that is not an option for me.
As it is now, it should be outputting:
[this, is, example, of, call]
Currently it is outputting: [this, is, null, example, of]
Any and all help will be much appreciated!
You need 2 indices in the second loop, since you are iterating over two arrays (the input array and the output array) having different lengths.
Besides, newLength is a confusing name, since it doesn't contain the new length. It contains the difference between the input array length and the output array length. You can change its value to match its name.
int newLength = arr.length;
for(int i = 0; i < arr.length; i++)
{
if(arr[i].contains(toRemove))
{
newLength--;
}
}
String[] result = new String[newLength];
int count = 0; // count tracks the current index of the output array
for(int i = 0; i < arr.length; i++) // i tracks the current index of the input array
{
if(!arr[i].contains(toRemove)) {
result[count] = arr[i];
count++;
}
}
return result;
There's the error that #Eran pointed out in your code, which can solve your problem. But I'm going to discuss another approach.
For now, you're first iterating over the entire array to find the number of occurrences to remove, and then, you're iterating over the array to remove them. Why don't you just iterate over the array, just to remove them. (I know, your first loop is helping you to determine the size of the output array, but you don't need that if you use some List like ArrayList etc.)
List<String> resultList = new ArrayList<String>();
for(int i = 0; i < arr.length; i++)
{
if(!arr[i].contains(toRemove))
{
resultList.add(arr[i]);
}
}
And you can return the resultList, but if you really need to return an array, you can convert the resultList to an array like this:
String [] resultArray = resultList.toArray(new String[resultList.size()]);
And then return this array. See this approach live here on ideone.
Try this Java8 version
List<String> test = Arrays.asList("this", "is", "the", "example", "of", "the", "call");
test.stream()
.filter(string -> !string.equals("the"))
.collect(Collectors.toList())
.forEach(System.out::println);
You can use Java Stream instead, it will give you the expected result and also your code will be clearer and really smaller.
See the method below I wrote that solves your problem.
public static String[] removeFromArray(String[] arr, String toRemove) {
return Arrays.stream(arr)
.filter(obj -> !obj.equals(toRemove))
.toArray(String[]::new);
}
If you're unfamiliar with java Stream, please see the doc here
The following code removes all occurrences of the provided string.
Note that I have added few lines for validate the input, because if we pass a null array to your program, it would fail. You should always validate the input in the code.
public static String[] removeFromArray(String[] arr, String toRemove) {
// It is important to validate the input
if (arr == null) {
throw new IllegalArgumentException("Invalid input ! Please try again.");
}
// Count the occurrences of toRemove string.
// Use Objects.equals in case array elements or toRemove is null.
int counter = 0;
for (int i = 0; i < arr.length; i++) {
if (Objects.equals(arr[i], toRemove)) {
counter++;
}
}
// We don't need any extra space in the new array
String[] result = new String[arr.length - counter];
int resultIndex = 0;
for (int i = 0; i < arr.length; i++) {
if (!Objects.equals(arr[i], toRemove)) {
result[resultIndex] = arr[i];
resultIndex++;
}
}
return result;
}

Possible to find whether a String array value equals any random typed string?

Let's say I got this array:
String[][]array = new String[5][5];
array[2][2] = desperate;
Would it be possible to find whether
String s = "desperate"; - equals any array element without using a for loop, and without having to manually enter the row column combination of the array assigned the value "desperate"?
while loop instead of for loop
int i = 0;
int j = 0;
while (i < n)
{
while (j < m)
{
if (array[i][j].equals("..."))
{
///
}
j++;
}
i++;
}
Use enhanced-for loop: -
String [][] array = new String[2][2];
array[1][1] = "desperate";
array[0][1] = "despee";
array[1][0] = "despete";
array[0][0] = "dete";
for (String[] innerArr: array) {
for (String value: innerArr) {
if (value.equals("desperate")) {
System.out.println(value + " == desperate");
}
}
}
Output: - desperate == desperate
A better way that I would suggest is to use ArrayList<String> to store your items.. Then you can just call contains() method to check whether the list contains that element..
List<String> listString = new ArrayList<String>();
listString.add("desperate");
listString.add("despe");
if (listString.contains("desperate")) {
System.out.println("True");
}
Output: - True
Assuming that you can't (for any reasons) change your array to another collection type:
String[][]array = new String[5][5];
array[2][2] = "desperate";
public boolean contains(String str){
return new HashSet<String>((List<String>)Arrays.asList(array)).contains(str);
}
Better than transforming it to a List since HashSet's contains() method is O(1) and the one from List is O(n).
The only way to avoid using a loop (and it not clear why you would want to) is to use a Map which you pre-build with all the strings and indexes.

String[] length count

I am declaring a String array as:
String[] items = new String[10];
items[0] = "item1";
items[1] = "item2";
How can I find length of items in an efficient way that it contains only 2 elements. items.length returns 10.
I am running a loop already which runs to its length. I want to so something with this code without adding new code/loop to count number of not-null elements. What can I replace with items.length
for (int i = 0; i < items.length; i++) {
...
}
No. You will need to loop and see how many non-null elements there are.
Consider using e.g. an ArrayList<String> instead of a raw array.
UPDATE
To answer the new part of your question, your loop can become:
for (int i = 0; (i < items.length) && (items[i] != null); i++) {
...
}
Why not use a collection:
Vector <String> items;
items.add("item1");
items.add("item2");
int length = items.size();
It is 10 already it is just that 8 of the object are set to null so you could do following
int count = 0 ;
if(items!=null){
for(String str : items){
if(str != null){
count ++;
}
}
}
With the modified question in mind, you can absolutely do nothing. There is no attribute giving you the count of not null elements, so either you'd take another collection or you'd check each value for null.
I think may this will help u
public class T1 {
public static void main(String[] args) {
String[] items = new String[10];
items[0] = "item1";
items[1] = "item2";
System.out.println(getActualSize(items));
}
public static int getActualSize(String[] items)
{
int size=0;
for(int i=0;i<items.length;i++)
{
if(items[i]!=null)
{
size=size+1;
}
}
return size;
}
}
You need to iterate and check for null.
int count = 0;
for(int i = 0; i < items.length; i++){
if(items[i] != null){
count++;
}
}
count will give the number of occupied elements
To find a number of all non-null elements in array/collection (that are not neccesary in the beginning of array) you can use elegant guava solution: Iterables.size(Iterables.filter(items, Predicates.notNull())).

deleting a string

I have an array of strings, and I want to delete a particular string from that array. How can I do that? My code is:
private void nregexp(){
String str_nregexp = i_exp_nregexp.getText();
boolean b;
for(int i=0; i<selectedLocations.length; i++){
b= selectedLocations[i].indexOf(str_nregexp) > 0;
if(b){
String i_matches = selectedLocations[i];
........
........
}
}
}
I have to remove i_matches from selectedLocations.
I depends what you mean by "delete a particular String from an array". If you wish to remove its value, you can simply set its value to null, however if you mean actually remove that element from the array (you have an array of 5 elements and you want the result after deleting the element to be 4), this is not possible without copying the array with the item removed.
If you want this behavior, you might want to take a look at a dynamic list such as ArrayList or LinkedList
Edit: If you wanted a simple method to copy the array into an array with the String removed, you could do something like:
List<Foo> fooList = Arrays.asList(orgArray);
fooList.remove(itemToRemove);
Foo[] modifiedArray = fooList.toArray();
You will need to copy the array to a smaller array, omitting the string you don't want. If this is a common situation, you should consider using something other than an array, such as LinkedList or ArrayList.
If you really want to do it yourself, here is an example:
import java.util.Arrays;
public class DelStr {
public static String[] removeFirst(String[] array, String what) {
int idx = -1;
for (int i = 0; i < array.length; i++) {
String e = array[i];
if (e == what || (e != null && e.equals(what))) {
idx = i;
break;
}
}
if (idx < 0) {
return array;
}
String[] newarray = new String[array.length - 1];
System.arraycopy(array, 0, newarray, 0, idx);
System.arraycopy(array, idx + 1, newarray, idx, array.length - idx - 1);
return newarray;
}
public static void main(String[] args) {
String[] strings = { "A", "B", "C", "D" };
System.out.printf("Before: %s%n", Arrays.toString(strings));
System.out.printf("After: %s%n",
Arrays.toString(removeFirst(strings, "D")));
}
}
You cannot change the length of the array, after initializing an array its length is set. So you cannot delete the element directly, you can only replace it, also with null.
String[] arr = new String[10];
// fill array
...
// replace the fifth element with null
arr[4] = null;
If you want to change the length of the Array you should try a list instead:
List<String> list = new ArrayList<String>();
// fill list
...
// remove the fifth element
list.remove(4);
Could you show us your code? Why don't you use ArrayList, as it has a remove(index) and remove(object) support?
Edit: Perhaps
private void nregexp() {
String str_nregexp = i_exp_nregexp.getText();
boolean b;
List<String> list = new ArrayList<String>(Arrays.asList(selectedLocations));
for(Iterator<String> it = list.iterator(); i.hasNext();){
String e = it.next();
b = e.indexOf(str_nregexp) > 0;
// b = e.matches(str_regexp); // instead?
if(b){
String i_matches = s;
it.remove(); // we don't need it anymore
........
........
}
}
selectedLocations = list.toArray(new String[list.size()]);
}
I've reached this solution that allows you to remove all the elements that equal the removal element:
private static <T> T[] removeAll(T[] array, T element) {
if (null == array)
throw new IllegalArgumentException("null array");
if (null == element)
throw new IllegalArgumentException("null element");
T[] result = (T[]) Array.newInstance(array.getClass().getComponentType(), array.length);
int j = 0;
for (int i = 0; i < array.length; i++) {
if (!element.equals(array[i]))
result[j++] = array[i];
}
return Arrays.copyOf(result, j);
}
I also did some benchmarking and this solution is definitely better then using Lists. Although, if performance is not a problem here, I would use Lists.
If you really need to remove only one element (the first) #kd304 has the solution.

Categories

Resources