列表框中的即时搜索算法

所以,我有一个包含x个项目的列表框。 在列表框的顶部,我有一个TextBox(这是搜索字段)。 我尝试开发一种算法,如果它不包含searchword(代码中的变量关键字),则从列表框中删除项目。 这应该发生在用户输入的每个键上(即时)。 所以,代码:

private void _keywordTextBox_TextChanged(object sender, EventArgs e) { string keyword = _keywordTextBox.Text; if (keyword == searchtext || isSpace) // do nothing if space is typed - searchtext is a templatetext in the textbox ("type here to search...") return; // ignore else if (keyword == "") { listBox.Items.Clear(); foreach (string s in originalList) listBox.Items.Add(s); } else { List selection = new List(); foreach (string s in originalList) // originalList is the listbox at startup selection.Add(s); listBox.BeginUpdate(); string[] keywordSplit = keyword.Split(' '); try { for (int i = originalList.Count - 1; i >= 0; i--) { string[] selectionSplit = selection[i].Split(' '); int l = 0; // number of hits for (int j = 0; j < selectionSplit.Length; j++) { for (int k = 0; k < keywordSplit.Length; k++) { if (selectionSplit[j].ToLower().Contains(keywordSplit[k].ToLower())) { l++; break; } } } if (l  0) listBox.SetSelected(0, true); // Select first item in listbox listBox.EndUpdate(); } } } 

这个问题很难描述,除了它没有按预期工作。 据我所知,这种行为是零星的。

如果我搜索“ck flow”,我应该得到stackoverflow的命中。 更重要的是,如果我删除字符(删除退格键)也应该有效。 任何人?

编辑:更多详情:

根据用户搜索的内容,列表框应在每次击键时缩小和增长。 列表框应该保留与用户输入的关键字匹配的每个项目,并过滤掉不匹配的项目。

或者您可以尝试制定正则表达式:

 private void textBox1_TextChanged(object sender, EventArgs e) { string keyword = textBox1.Text; if (string.IsNullOrEmpty(keyword.Trim())) { listBox1.Items.Clear(); listBox1.Items.AddRange(_originalList.ToArray()); } else { Regex regex = new Regex(GetRegexPatternFromKeyword(keyword)); List selection = _originalList.Where(s => regex.IsMatch(s)).ToList(); listBox1.Items.Clear(); listBox1.Items.AddRange(selection.ToArray()); } } private static string GetRegexPatternFromKeyword(string keyword) { string[] words = keyword.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(word => "(?=.*" + word.Replace(")", @"\)") + ")").ToArray(); return string.Join("", words); } 

免责声明 :在某些情况下,输入会“破坏”正则表达式模式

你的代码经常增加。 例如;

带有搜索词’aaa bbb’的文字’aaa aaa aaa’将给出1的l,因为每次你找到’aaa’你都会增加l。 所以这将是一场比赛,即使从未找到’bbb’。

您可以通过删除keywordsplit的已找到部分并在每次搜索新选择行之前重新创建keywordsplit来解决此问题(以及其他问题)。

 l++; break; 

 l++ keywordSplit.RemoveAt[k]; break; 

并移动

 string[] keywordSplit = keyword.Split(' '); 

就在你开始k循环之前

尽管如此,我觉得可能有更好的方法来实现你想要的东西,它应该更清洁,更快速的代码。

我得到了它的工作。 @IvoTops帮助我朝着正确的方向发展。 只需首先循环所有关键字,然后选择。

  for (int j = 0; j < keywordSplit.Length; j++) { for (int k = 0; k < selectionSplit.Length; k++) { if (selectionSplit[k].ToLower().Contains(keywordSplit[j].ToLower())) { l++; break; } } } 

好像现在工作正常。