This question already has an answer here:
Remove a common word from each string value in an array
(1 answer)
Closed 6 years ago.
I have an array of Strings that contains: Extra Water, Juice, and Extra Milk, so I am wondering how would I get rid of the extras and use the only second word in the string so that the expected output is Water, Juice, and Milk.
If all you want to do is remove a specific substring then:
String[] array = {"Extra Water", "Juice", "Extra Milk"};
array = Arrays.stream(array).map(s-> s.replaceAll("Extra", "")).toArray();
This uses Java 8 streams but you could do it just as simply with iteration.
Use String.split(' ') to split the string by a space, then check the result to see if the string length == 2. If so, then take the second element of the array, otherwise the first.
for( int i = 0; i < array.length; i++ ) {
String[] parts = array[i].split(' ');
if( parts.length == 2 ) {
array[i] = parts[1];
}
}
EDIT: If you want to remove all duplicate words, you could do the following using two passes over the array:
// Pass 1 -- find all duplicate words
Set<String> wordSet = new HashSet<>();
Set<String> duplicateSet = new HashSet<>();
for (int i = 0; i < array.length; i++) {
String[] parts = array[i].split(" ");
for (String part : parts) {
if (!wordSet.contains(part)) {
// Haven't seen this word before
wordSet.add(part);
} else {
// This word is a duplicate word
if (!duplicateSet.contains(part)) {
duplicateSet.add(part);
}
}
}
}
// Pass 2 -- remove all words that are in the duplicate set
for (int i = 0; i < array.length; i++) {
String[] parts = array[i].split(" ");
String dedupedString = "";
for (String part : parts) {
if (!duplicateSet.contains(part)) {
dedupedString += part + " ";
}
}
array[i] = dedupedString;
}
Simply you need to iterate over each element of the array and replace the "Extra" in each element of the array and then trim the white spaces.
String[] array = {"Extra Water", "Juice", "Extra Milk"};
for (int i = 0; i < array.length; i++) {
array[i] = array[i].replace("Extra", "").trim();
}
for (String each : array) {
System.out.println(each);
}
Related
I have a string:
str = "Hello there"
I am removing the whitespace:
String[] parts = str.split("\\s+");
Creating a List and populating it with the parts:
List<String> theParts = new ArrayList<String>();
for (int i = 0; i < parts.length; i++) {
theParts.add(parts[i]);
}
The size of the List is 2.Now, I want to increase it's size in order to be the same size as another list.
Let's say the other list has size 3.
So, I check:
if (otherList.size() > theParts.size()) {
and then, I want to change the theParts list in order to contain an empty space (the number which shows how much greater the otherList is) between it's parts.
So, I want theParts to be (add a space at every odd position):
theParts[0] = "Hello"
theParts[1] = " "
theParts[2] = "there"
I am not sure if this can be happen with Lists, but I can't think another solution.
Or use something like join (doesn't work, just an idea to use something like this):
if (otherList.size() > theParts.size()) {
for (int i = 0; i < otherList.size(); i++) {
if (i%2 !=0) {
String.join(" ", theParts);
}
}
}
Just insert the spaces as you're populating the list:
List<String> theParts = new ArrayList<>(2 * parts.length - 1);
for (int i = 0; i < parts.length; i++) {
if (i > 0) theParts.add(" ");
theParts.add(parts[i]);
}
You could use a word break regex:
public void test() throws Exception {
String str = "Hello there";
List<String> strings = Arrays.asList(str.split("\\b"));
for ( String s : strings ) {
System.out.println("'"+s+"'");
}
}
this will retain all of the spaces for you.
'Hello'
' '
'there'
for(String dis : theParts){
newParts.add(dis);//'newPart is another list '
String last = parts[parts.length -2]; // until new list read last element
if(!last.equals(dis)){
newParts.add(" ");
}if(last.equals(dis)){
newParts.add(" ");
}
}
I want to write a java program that separates the even chars in an String array. I made this program like this and it is working :
String [] x = new String[5] ;
x[0] = "Hello" ;
x[1] = "My" ;
x[2] = "Name" ;
x[3] = "is" ;
x[4] = "John" ;
for(int i=0;i<x.length;i++) {
if(x[i].length()%2==0) {
System.out.println(x[i]);
}
}
Now I wanna make the program work with a List declaration like this :
List<String> list=Arrays.asList("HELLO","MY","NAME","IS","ALICE") ;
How can I continue from this point ? I TRIED with some sort of "for" iteration but I don't know how to recognize element by element from this List.
Enhanced for loop to the rescue
List<String> list=Arrays.asList("HELLO","MY","NAME","IS","ALICE");
for(String s : list) {
if(s.length()%2==0) {
System.out.println(s);
}
}
Also, just to point out, you can initialize that array as:
String[] x = {"Hello", "My", "Name", "is" , "John"};
which also supports enhanced for loop:
String[] x = {"Hello", "My", "Name", "is" , "John"};
for(String s : x) {
if(s.length()%2==0) {
System.out.println(s);
}
}
you should run on each String a method that extract the even charachters and create from them a string like this :
public void printEvenChars(String str) {
StringBuilder sbEven = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
if ( i % 2 == 0) {
sbEven.append(str.charAt(i));
}
}
System.out.println(sbEven.toString());
}
if you mean filter even legnth strings you can do it in one line
list.stream().filter(x -> (x.length() % 2) == 0).collect(Collectors.toList());
currently I'm trying to make a method that does the following:
Takes 3 String Arrays (words, beforeList, and afterList)
Looks for words that are in both words and in beforeList, and if found, replaces with word in afterList
Returns a new array that turns the elements with characters in afterList into new elements by themselves
For example, here is a test case, notice that "i'm" becomes split into two elements in the final array "i" and "am":
String [] someWords = {"i'm", "cant", "recollect"};
String [] beforeList = {"dont", "cant", "wont", "recollect", "i'm"};
String [] afterList = {"don't", "can't", "won't", "remember", "i am"};
String [] result = Eliza.replacePairs( someWords, beforeList, afterList);
if ( result != null && result[0].equals("i") && result[1].equals("am")
&& result[2].equals("can't") && result[3].equals("remember")) {
System.out.println("testReplacePairs 1 passed.");
} else {
System.out.println("testReplacePairs 1 failed.");
}
My biggest problem is in accounting for this case of whitespaces. I know the code I will post below is wrong, however I've been trying different methods. I think my code right now should return an empty array that is the length of the first but accounted for spaces. I realize it may require a whole different approach. Any advice though would be appreciated, I'm going to continue to try and figure it out but if there is a way to do this simply then I'd love to hear and learn from it! Thank you.
public static String[] replacePairs(String []words, String [] beforeList, String [] afterList) {
if(words == null || beforeList == null || afterList == null){
return null;
}
String[] returnArray;
int countofSpaces = 0;
/* Check if words in words array can be found in beforeList, here I use
a method I created "inList". If a word is found the index of it in
beforeList will be returned, if a word is not found, -1 is returned.
If a word is found, I set the word in words to the afterList value */
for(int i = 0; i < words.length; i++){
int listCheck = inList(words[i], beforeList);
if(listCheck != -1){
words[i] = afterList[listCheck];
}
}
// This is where I check for spaces (or attempt to)
for(int j = 0; j < words.length; j++){
if(words[j].contains(" ")){
countofSpaces++;
}
}
// Here I return an array that is the length of words + the space count)
returnArray = new String[words.length + countofSpaces];
return returnArray;
}
Here's one of the many ways of doing it, assuming you have to handle cases where words contain more than 1 consecutive spaces:
for(int i = 0; i < words.length; i++){
int listCheck = inList(words[i], beforeList);
if(listCheck != -1){
words[i] = afterList[listCheck];
}
}
ArrayList<String> newWords = new ArrayList<String>();
for(int i = 0 ; i < words.length ; i++) {
String str = words[i];
if(str.contains(' ')){
while(str.contains(" ")) {
str = str.replace(" ", " ");
}
String[] subWord = str.split(" ");
newWords.addAll(Arrays.asList(subWord));
} else {
newWords.add(str);
}
}
return (String[])newWords.toArray();
I am trying to do an assignment that works with Arrays and Strings. The code is almost complete, but I've run into a hitch. Every time the code runs, it replaces the value in the index of the output array instead of putting the new value in a different index. For example, if I was trying to search for the words containing a prefix "b" in the array of strings, the intended output is "bat" and "brewers" but instead, the output comes out as "brewers" and "brewers". Any suggestions? (ps. The static main method is there for testing purposes.)
--
public static void main(String[] args) {
String[] words = {"aardvark", "bat", "brewers", "cadmium", "wolf", "dastardly", "enigmatic", "frenetic",
"sycophant", "rattle", "zinc", "alloy", "tunnel", "nitrate", "sample", "yellow", "mauve", "abbey",
"thinker", "junk"};
String prefix = "b";
String[] output = new String[wordsStartingWith(words, prefix).length];
output = wordsStartingWith(words, prefix);
for (int i = 0; i < output.length; i++) {
System.out.println("Words: " + i + " " + output[i]);
}
}
public static String[] wordsStartingWith(String[] words, String prefix) {
// method that finds and returns all strings that start with the prefix
String[] returnWords;
int countWords = 0;
for (int i = 0; i < words.length; i++) {
// loop to count the number of words that actually have the prefix
if (words[i].substring(0, prefix.length()).equalsIgnoreCase(prefix)) {
countWords++;
}
}
// assign length of array based on number of words containing prefix
returnWords = new String[countWords];
for (int i = 0; i < words.length; i++) {
// loop to put strings containing prefix into new array
for (int j = 0; j < returnWords.length; j++) {
if (words[i].substring(0, prefix.length()).equalsIgnoreCase(prefix)) {
returnWords[j] = words[i];
}
}
}
return returnWords;
}
--
Thank You
Soul
Don't reinvent the wheel. Your code can be replaced by this single, easy to read, bug free, line:
String[] output = Arrays.stream(words)
.filter(w -> w.startsWith(prefix))
.toArray(String[]::new);
Or if you just want to print the matching words:
Arrays.stream(words)
.filter(w -> w.startsWith(prefix))
.forEach(System.out::println);
Its because of the code you have written. If you would have thought it properly you would have realized your mistake.
The culprit code
for (int j = 0; j < returnWords.length; j++) {
if (words[i].substring(0, prefix.length()).equalsIgnoreCase(prefix)) {
returnWords[j] = words[i];
}
}
When you get a matching word you set whole of your output array to that word. This would mean the last word found as satisfying the condition will replace all the previous words in the array.
All elements of array returnWords gets first initialized to "bat" and then each element gets replaced by "brewers"
corrected code will be like this
int j = 0;
for (int i = 0; i < words.length; i++) {
if (words[i].substring(0, prefix.length()).equalsIgnoreCase(prefix)) {
returnWords[j] = words[i];
j++;
}
}
Also you are doing multiple iterations which is not exactly needed.
For example this statement
String[] output = new String[wordsStartingWith(words, prefix).length];
output = wordsStartingWith(words, prefix);
can be rectified to a simpler statement
String[] output = wordsStartingWith(words, prefix);
The way you're doing this is looping through the same array multiple times.
You only need to check the values once:
public static void main(String[] args) {
String[] words = {"aardvark", "bat", "brewers", "cadmium", "wolf", "dastardly", "enigmatic", "frenetic",
"sycophant", "rattle", "zinc", "alloy", "tunnel", "nitrate", "sample", "yellow", "mauve", "abbey",
"thinker", "junk"};
String prefix = "b";
for (int i = 0; i < words.length; i++) {
if (words[i].toLowerCase().startsWith(prefix.toLowerCase())) {
System.out.println("Words: " + i + " " + words[i]);
}
}
}
Instead of doing two separate loops, try just having one:
String[] returnWords;
int[] foundWords = new int[words.length];
int countWords = 0;
for (int i = 0; i < words.length; i++) {
// loop to count the number of words that actually have the prefix
if (words[i].substring(0, prefix.length()).equalsIgnoreCase(prefix)) {
foundWords[index] = words[i];
countWords++;
}
}
// assign length of array based on number of words containing prefix
returnWords = new String[countWords];
for (int i = 0; i < countWords; i++) {
returnWords[i] = foundWords[i];
}
My method has another array (foundWords) for all the words that you found during the first loop which has the size of words in case every single word starts with the prefix. And index keeps track of where to place the found word in foundWords. And lastly, you just have to go through the countWords and assign each element to your returnWords.
Not only will this fix your code but it will optimize it so that it will run faster (very slightly; the bigger the word bank is, the greater fast it will search through).
So if I have this: 'my message that needs checking'.
And I have a string with this: [1][3][4]. These are the elements of the message that I want to remove (e.g. 'my' would be element 1, 'that' would be element 3).
How would I loop through this message and remove the elements in this other string?
Example:
String messageToFilter = "my message that needs checking";
String filter = "[1]-[3]-[4]";
for (String curElement : filter.split("-")) {
//If I remove element [0], element [3] is then moved to [2]; so not sure what to do!
}
//So at this stage I need the messageToFilter, but with the elements from filter removed.
//In the example above this would output 'message checking'.
First you need to get the indexes from the filter as integers, and then remove the words at this position in the sentence.
String messageToFilter = "my message that needs checking";
// Split into an array of words
String[] words = messageToFilter.split("\\s+");
// get the indexes
Pattern pat = Pattern.compile("(\\d+)");
Matcher mat = pat.matcher("[1]-[3]-[4]");
while (mat.find()) {
int index = Integer.parseInt(mat.group());
// set the matching word to null (assuming the indexes start at 1)
words[index-1] = null;
}
// Rebuild the message
StringBuilder messageFiltered = new StringBuilder();
for (String w : words) {
if (w != null) {
messageFiltered.append(w).append(" ");
}
}
System.out.println(messageFiltered.toString());
Output:
message checking
Loop backwards over the array of items to remove
String[] toFilter = filter.split("-");
for ( int i = toFilter.length() - 1; i >= 0; i-- ){
///remove the items
}
I propose you create a second string (or List) as your result.
String messageToFilter = "my message that needs checking";
String filter = "[1]-[3]-[4]";
String result = null;
for (String curElement : filter.split("-")) {
if(curElement.equalsIgnoreCase("[3]")) {
result = curElement;
break; // or whatever you need to do with the result.
}
}
Looping backwards and replacing the indexes with space, then construct a new String without space.
String filterString = "[1]-[3]-[4]";
String messageToFilter = "my message that needs checking";
String[] words = messageToFilter.split("\\s");// filterString for white space
String[] indexes = StringUtils.split(filterString, "]|\\[|-");// filterString the numbers out
for (int i = words.length - 1; i >= 0; i--) {
for (int j = indexes.length - 1; j >= 0; j--) {
if (i > j)
break;
if (i == j) {
int valueAtIndex = Integer.parseInt(indexes[i]);
words[valueAtIndex-1] = "";
break;
}
}
}
StringBuffer bf = new StringBuffer();
for (String word : words) {
if(word!="")
bf.append(word).append(" ");
}
System.out.println(bf.toString());
You could try :
public static void main(String[] argss){
String messageToFilter = "my message that needs checking";
String filter = "[1]-[3]-[4]";
ArrayList<Integer> lst=new ArrayList<Integer>();
String[] fltr = filter.split("-");
for (String curElement : fltr) {
// populate lst with indexes to filter !
lst.add(Character.getNumericValue(curElement.charAt(1)));
}
String result="";
String[] msgSplitted=messageToFilter.split(" ");
for(int i=0; i<msgSplitted.length;i++){
if(!lst.contains(i+1))
{
//Checks if this index i must be flitered
//Otherwise, add matching word to result
result=result+" "+msgSplitted[i];
}
}
System.out.print(result); //your result
}