Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Improve search in array

Tags:

java

android

I'm a newbie to Android and Java so please be nice :)

I have an EditText in my application which is used to search for a particular string in a String[]

My code works well, but not as I want:

ArrayList<String> allProd = new ArrayList<String>;
ArrayList<String> allProd_sort = new ArrayList<String>;

allProd = [the table is brown, the cat is red, the dog is white];

String[] allProdString = allProd.toArray(new String[allProd.size()]);

...

 //inputSearch is the EditText
 inputSearch.addTextChangeListener (new TextWatcher() {

   ...

   @Override
   public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) { 

     int textLength = inputSearch.getText().length();
     String text = inputSearch.getText().toString();

     for (int y = 0; y< allProdString.length; y++) {

        //in my case i want that the search start when there are min 3 characters in inputSearch
        if(textLength <= allProdString[y].length() && textLength >=3) {

           if (Pattern.compile(Pattern.quote(text), Pattern.CASE_INSENSITIVE)
                                .matcher(allProdString[y]).find()) {

               allProd_sort.add(allProdString[y]);

           }

        }
     }

   }

 });

This code produces these results:

if I search for "table is" => allProd_sort will be [the table is brown]

but if I search for "table brown" => allProd_sort will be empty but I want [the table is brown]

how can I improve this?

thanks everybody

like image 719
Ilario Avatar asked Oct 02 '22 18:10

Ilario


2 Answers

You need to change the pattern. At the moment the string needs to contain exactly what you entered. If instead of the space you put "table.*brown" it would match.

You can either have the user enter the regex, or you can do a simplified thing yourself by replacing all whitespace in the query string with ".*" before using it to match on.

You can read all about regular expressions here: http://docs.oracle.com/javase/tutorial/essential/regex/

like image 183
Tim B Avatar answered Oct 05 '22 05:10

Tim B


Ok - first optimization: Only enter the loop, if your initial requirement (Searchtext >=3) is true:

@Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {

  int textLength = inputSearch.getText().length();

  if (textLength < 3) return;

  String[] searchPattern = inputSearch.getText().toString().toLowerCase().split("\\s+");

  for (int y = 0; y< allProdString.length; y++) {

    if(textLength <= allProdString[y].length()) {
       if (matchSearch(allProdString[y].toLowerCase(), searchPattern)) {

           allProd_sort.add(allProdString[y]);

       }

    }
 }

If you only want to match lines, where all words are contained in the same sequence you can simply create a regular Expression like Tim B said.

But if you also want to match strings which contain the words anywhere search search "brown table" -> [the table is brown] then you need a little loop:

public boolean matchSearch(String s, String[] searches) {
    for (String search : searches) {
        if (!s.contains(search) return false; // If the word is not in the string FALSE
    }
    return true; // If all words were found in the string, it is a match!
}

To make this a bit clearer -> brown.*table will only match Strings where table comes after brown... I don't think you can easily create an efficient RegEx to check if each word is at least one time anywhere in the string...

like image 45
Falco Avatar answered Oct 05 '22 04:10

Falco