【问题标题】:How to filter list of string lists using string list如何使用字符串列表过滤字符串列表
【发布时间】:2017-05-10 11:33:07
【问题描述】:

我有一个使用字符串列表的对象填充的数据视图。我想通过在文本框中输入搜索词来选择合适的条目。

我的对象:

class my_object
{
    List<string> column1 = new List<string>();
    List<string> column2 = new List<string>();
    List<string> column3 = new List<string>();
    List<string> column4 = new List<string>(); 
}

我的数据视图条目:

List<my_object> entries = new List<my_object>();

我的目标是过滤 Windows 资源管理器中的搜索功能等条目,但不同之处在于我想包括四列,而不仅仅是带有文件名的列。 有没有可能做到这一点?

我尝试过的:

internal static List<my_object> SearchObject(this List<my_object> Source, List<string> SearchWords)
{
    List<my_object> results = new List<my_object>();

    foreach (my_object m in Source)
    {
        foreach(string s in SearchWords)
        {
            // Filter Column 1
            foreach(string c1 in m.column1)
            {
                if(c1.IndexOf(s) != -1)
                {
                    results.Add(m);
                    break;
                }
            }
        } 
    }

    return results;

    // Problem:
    // This function only filters the first column.
    // If I want to filter the next column, I have to break all 'foreach' blocks 
    // except the '(my_object m in Source)' block...

    // It the 'break' would work for more the one loop, this method would work...
}

希望你能帮助我。

【问题讨论】:

    标签: c# string list search filter


    【解决方案1】:

    为什么不能像Contains()这样使用方法

    foreach (my_object m in Source)
    {
        foreach(string s in SearchWords)
        {
            If(m.column1.Contains(s) || m.column2.Contains(s) || m.column3.Contains(s))
            {
                 results.Add(m);   
                 break;
            }         
        } 
    }
    

    【讨论】:

      【解决方案2】:

      这样做的一种方法是重构您的类以允许搜索。这是一个使用索引的示例:

      class my_object
      {
          class Coordinates
          {
              public int _column = 0;
              public int _row = 0;
              public Coordinates(int row, int column)
              {
                  _column = column;
                  _row = row;
              }
          }
          List<List<string>> columns = new List<List<string>>(4);
          Dictionary<string, List<Coordinates>> searchIndex = new Dictionary<string, List<Coordinates>>();
          public my_object()
          {
              for (int i = 0; i < columns.Count; i++)
              {
                  columns[i] = new List<string>();
              }
          }
          //This will create entries for each consecutive substring in each word that you add.
          public void AddWord(string word, int column)
          {
              for (int i = 0; i < word.Length; i++)
              {
                  int limit = word.Length - i;
                  for (int j = 1; j < limit; j++)
                  {
                      string temp = word.Substring(i, j);
                      if (!searchIndex.ContainsKey(temp))
                      {
                          searchIndex.Add(temp, new List<Coordinates>());
                      }
                      searchIndex[temp].Add(new Coordinates(columns.Count, column));
                  }
      
              }
              columns[column].Add(word);
          }
          //This will return a list of list of strings that contain the search term.
          public List<List<string>> Find(string term)
          {
              List<List<string>> outVal = new List<List<string>>(4);
              if(searchIndex.ContainsKey(term))
              {
                  foreach(Coordinates c in searchIndex[term])
                  {
                      outVal[c._column].Add(columns[c._column][c._row]);
                  }
              }
              return outVal;
          }
      }
      

      【讨论】:

        【解决方案3】:

        您可以将所有子列表合并到一个列表中,然后将 Any 扩展名应用于要搜索的单词列表

        foreach (my_object m in Source)
        {
            List<string> allStrings = m.Column1.Union(m.Column2)
                                               .Union(m.Column3)
                                               .Union(m.Column4)
                                               .ToList();
            bool exists = SearchWords.All(x => allStrings.IndexOf(x) != -1));    
            if(exists)
                results.Add(m); 
        }
        

        但是我会针对更传统的解决方案测试性能

        【讨论】:

        • 感谢您的快速回答。它的工作速度非常快,但不幸的是它只适用于整个单词,并且它选择单词 x 或单词 y 为真的项目。我只想拥有单词 x 和单词 y 为真的项目...
        • 嗯,第一个问题我们可以用IndexOf替换Contains,第二个问题不是很清楚。你能解释一下单词 x 和单词 y 的含义吗?
        • ok,indexof 是明确的,x 和 y 表示搜索词
        • 对不起,我还是不明白。 SearchWords 是一个字符串列表。如果您发现此列表中的单词包含在 my_object m 的任何子列表中,您希望将当前 m 添加到结果中,然后传递到下一个my_object 实例。此时搜索 SearchWords 的另一个词是否包含在 my_object 的同一实例中是无用的,因为您已经添加了当前 my_object m到结果列表。不,那时我还没有真正理解你的问题。
        • 如果 searchwords 中的每个单词都包含,我只想将 my_object 添加到结果中
        猜你喜欢
        • 1970-01-01
        • 2013-09-24
        • 1970-01-01
        • 2022-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-18
        相关资源
        最近更新 更多