1

Hello I need filter an ArrayList

I have a ArrayList with following items:

"Hello world" "Hello man" "Hello woman" "Goodbye world" "Goodbye man" "Goodbye woman"

then on TextBox I added a textchanged listener (Android).What i want is if I write "he wo" separated by space, it displays "Hello world" and "Hello woman".

I've been fighting with this about an hour and only I got is that if I write "he wo" I get the following items: "Hello world", "Hello man", "Hello woman", "Goodbye world". Here is the code

 et.addTextChangedListener(new TextWatcher()
    {
        public void afterTextChanged(Editable s)
        {
          // Abstract Method of TextWatcher Interface.
        }
        public void beforeTextChanged(CharSequence s,
        int start, int count, int after)
        {
        // Abstract Method of TextWatcher Interface.
        }
        public void onTextChanged(CharSequence s, int start, int before, int count)
        {
            //listabusClientes = new ArrayList<busCliente>();
            paraulesBuscar = s.toString().split(" "); //Array of string
            sortarray = new ArrayList<busCliente>(); //ArrayList of class busCliente
            sortarray.clear();

            for(int x = 0; x < paraulesBuscar.length; x++){
                sortarray.clear();
                for (int i = 0; i < listabusClientes.size(); i++)
                {
                    if ((listabusClientes.get(i).getNom().toUpperCase().indexOf(paraulesBuscar[x].toUpperCase()) != -1) || (listabusClientes.get(i).getCodiClient().toUpperCase().indexOf(paraulesBuscar[x].toUpperCase()) != -1))
                    {
                        sortarray.add(listabusClientes.get(i)); 
                    }
                }
            }
            lv.setAdapter(new ListViewAdapter(buscar_client.this,
                     R.layout.simple_list_item_1, sortarray));
        }
  });

Edited algorithm

paraulesBuscar = s.toString().split(" ");
                                    sortarray = new ArrayList<busCliente>();
                                    sortarray.clear();

                                    for(int x = 0; x < paraulesBuscar.length; x++){
                                        sortarray.clear();
                                        for (int i = 0; i < listabusClientes.size(); i++)
                                        {   
                                            String[] clientSplit = listabusClientes.get(i).getNom().split(" ");

                                            for(int cs = 0; cs < clientSplit.length; cs++){
                                                System.out.println(clientSplit[cs]);
                                                if (clientSplit[cs].toUpperCase().contains(paraulesBuscar[x].toUpperCase()))
                                                {
                                                    sortarray.add(listabusClientes.get(i)); 

                                                }
                                            }

                                        }
                                    }
0

2 Answers 2

1

Here's how I would do:

  1. split "he wo" into words, using String.split(), to get an array of prefixes ["he", "wo"]
  2. iterate on the items. For each item, split it into words, to get an array of words ["Hello", "World"]
  3. Check that the array of words has at least the same length as the array of prefixes. If not, the item is rejected
  4. Iterate through the indices of the prefixes. For each index, get the prefix and the word. Convert the word to lower-case. Check that it starts with the prefix. All these methods are available in the String class. If it doesn't start with the prefix, the item is rejected.

This should get you started. Make sure to implement this algorithm as a separate method, itself splitted into sub-methods doing just one thing.

EDIT:

here's the last part of the algorithm (steps 3 and 4):

/**
 * Tells if every prefix has a corresponding word and if every word, lower-cased, 
 * starts with the corresponding prefix.
 */
private boolean allPrefixesMatch(String[] prefixes, String[] words) {
    if (words.length < prefixes.length) {
        return false;
    }
    for (int i = 0; i < prefixes.length; i++) {
        String prefix = prefixes[i];
        String word = words[i];
        if (!word.toLowerCase().startsWith(prefix)) {
            return false;
        }
    }
    return true;
}
Sign up to request clarification or add additional context in comments.

7 Comments

It do the same, I've did that you said, but I get the same results
Wait I just got a problem with my code :) Was coding in the wrong site
see my algorithm, I dont know If im doing exactly what you said.
No, you don't. First, you don't check the length of the array of words (step 3 of my algorithm). Second, you accept an item as soon as one of its words matches with the corresponding prefix (and you add it twice if its two words match with their corresponding prefix), instead of adding the item only if ALL its words match with their corresponding prefix.
I don't know how to do this, If you can edit my code, and post, You will make me very happy
|
1

I suggest you to use a different approch to the problem. Create a custom adapter that extends ArrayAdapter and implements a filterable interface.

In your adapter create a private class that extends Filter; you have to override two methods:

protected FilterResults performFiltering(CharSequence constraint) {.. }

and

protected void publishResults(CharSequence constraint,
            FilterResults results) {..}

In the first one you set the filtering rule, in your case you can verify that a string is contanined in your items. In the second method you publish the results filtered calling notifyDataSetChanged();

You correctly added a changeTextListener but in the onTextChanged you call the filter to perform the filtering operation:

aAdpt.getFilter().filter(s.toString());

where aAdpt is your custom adapter. I hope i was clear. If you have some doubt you can refer to my post here.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.