通过ArrayList为阵列名称进行自定义搜索

问题描述:

我试图在自定义适配器中使用getFilter方法实现搜索筛选器。通过ArrayList为阵列名称进行自定义搜索

有两种通过列表搜索的模型。

  • 搜索项目的title
  • 搜索项目的genre[]

但我只是在这里谈论genre)。

下面的代码工作正常,但我需要的仅仅是一个更自定义的方式来搜索genre[]

我想要实现的是:(我想什么):

multi-keyword搜索,每个分类均具有,分离。例如:genre1,genre2

(我做了什么)

当我键入genre1,genre2则给出了在流派这个序列中的项目,它不会给genre1,genre3,genre2,或者只是genre1

你能帮忙吗?

用getFilter:

@Override 
public Filter getFilter() { 
    Filter filter = new Filter() { 
     @Override 
     protected void publishResults(CharSequence constraint, FilterResults results) { 
      dataList = (List<ProductLocal>) results.values; 
      notifyDataSetChanged(); 
     } 
     @Override 
     protected FilterResults performFiltering(CharSequence constraint) { 
      FilterResults results = new FilterResults(); 
      List<ProductLocal> filteredList = new ArrayList<>(); 
      constraint = constraint.toString().toLowerCase(); 
      for (int i = 0; i < dataListFilter.size(); i++) { 
       ProductLocal dataNames = dataListFilter.get(i); 

       String genreStr = ""; 
       for (String str : dataNames.getGenre()) { 
        genreStr += str + ","; 
       } 

       if (dataNames.getTitle().toLowerCase().startsWith(constraint.toString()) 
       || genreStr.toLowerCase().contains(constraint.toString())) { 
        filteredList.add(dataNames); 
       } 
      } 
      results.count = filteredList.size(); 
      results.values = filteredList; 
      return results; 
     } 

    }; 
    return filter; 
} 
+0

@DastakWall你想要可科特林回答所有的搜索字词? –

AFAIU你想要的歌曲相匹配的fiter如果任何这些2个条件:

  1. 歌曲的标题与全启动搜索文本

  2. 该歌曲的类型包含由,(逗号)分隔的部分搜索文本

如果是这样,请尝试以下搜索逻辑:

 @Override 
     protected FilterResults performFiltering(CharSequence constraint) 
     { 
      FilterResults results = new FilterResults(); 
      List<ProductLocal> filteredList = new ArrayList<>(); 
      String searchText = constraint.toString().toLowerCase(); 
      String[] split = searchText.split(","); 
      ArrayList<String> searchGenres = new ArrayList<String>(split.length); 
      for (int i = 0; i < split.length; i++) 
      { 
       // remove spaces 
       String trim = split[i].trim(); 
       // skip empty entries 
       if (trim.length() > 0) 
        searchGenres.add(trim); 
      } 

      for (ProductLocal dataNames : dataListFilter) 
      { 
       // filter by title 
       if (dataNames.getTitle().toLowerCase().startsWith(searchText)) 
       { 
        filteredList.add(dataNames); 
       } 
       else 
       { 
        // filter by genres 
        // search for at least one common genre between song and search text 
        outer: 
        for (String songGenre : dataNames.getGenre()) 
        { 
         for (String searchGenre : searchGenres) 
         { 
          if (songGenre.toLowerCase().contains(searchGenre)) 
          { 
           filteredList.add(dataNames); 
           break outer; 
          } 
         } 
        } 
       } 
      } 
      results.count = filteredList.size(); 
      results.values = filteredList; 
      return results; 
     } 

这里唯一棘手的地方是break outer;。这是同时从两个for循环中分离出来的Java语法。这里的想法是,如果我们找到了匹配的constraint和歌曲之间的一些流派,我们的歌曲添加到filteredList,不想再次添加它,如果有更多的匹配类型。

P.S.如果通过很多搜索类型过滤成为性能问题,则可以考虑建立单一的正则表达式匹配一次或实施Aho–Corasick algorithm

您可以通过拆分,

String[] searmTearmArray= serachTerm.split(","); 

现在使用for循环中,您可以搜索这些词语搜索词。

+0

我试过了,这不起作用。 –

+0

什么是错误 –

+0

没有错误,但是当我在像'小提琴序列式风格,light'则给出了在流派这个序列的结果,它不会给有'小提琴,电的项目, light'。 –

请通过拆分约束字符串,如以下尝试:

@Override 
public Filter getFilter() { 
    @SuppressWarnings("UnnecessaryLocalVariable") 
    Filter filter = new Filter() { 
     @SuppressWarnings("unchecked") 
     @Override 
     protected void publishResults(CharSequence constraint, FilterResults results) { 
      dataList = (List<ProductLocal>) results.values; 
      notifyDataSetChanged(); 
     } 

     @Override 
     protected FilterResults performFiltering(CharSequence constraint) { 
      FilterResults results = new FilterResults(); 
      List<ProductLocal> filteredList = new ArrayList<>(); 

      for (int i = 0; i < dataListFilter.size(); i++) { 
       ProductLocal dataNames = dataListFilter.get(i); 

       int count = 0; 
       String[] terms = constraint.toString().split(","); 

       for (int j = 0; j < terms.length; j++) { 

        String term = terms[j]; 
        for (String str : dataNames.getGenre()) { 

         if (str.equals(term) || str.contains(term)) { 
          count++; 
          if (count == terms.length) { 
           filteredList.add(dataNames); 
          } 
         } 
        } 
       } 
      } 

      results.count = filteredList.size(); 
      results.values = filteredList; 
      return results; 
     } 

    }; 
    return filter; 
} 
+0

这不起作用,对于第一个关键字来说很好,但是在插入'后,'列表返回空 –

+0

请尝试编辑答案并让我知道它是否有效。 –

+0

一样的,但是这一次分裂后,名单将保持与第一次使用关键字找到的项目,没有任何功能的任何其他输入 –