Что касается вашего требования, попробуйте это
jQuery(document).on("change", ".DDLChoices", function (e) {
var comma_ChoiceIds = '';
var comma_ChoicesText = '';
$('input[class="DDLChoices"]').each(function (e) {
if (this.checked) {
comma_ChoiceIds = comma_ChoiceIds + $(this).val() + ',';
comma_ChoicesText = comma_ChoicesText + $(this).parent('label').parent() + ',';
}
});
$('#ChoiceIds').val(comma_ChoiceIds);
$('#ChoiceText').val(comma_ChoicesText);
});
@using (Html.BeginForm("Actionname", "Controllername", FormMethod.Post, new { id = "frmChoices" }))
{
@Html.HiddenFor(m => m.ChoiceText, new { @id = "ChoiceText" })
@Html.HiddenFor(m => m.ChoiceIds, new { @id = "ChoiceIds" })
<div class="form-group">
<div>
<table>
<tr>
<th>Name</th>
<th>Selected</th>
</tr>
@foreach (var item in @Model.Choices)
{
<tr>
<td> <label>@item.ChoicesText</label> </td>
<td> <input class="DDLChoices" value="@item.ChoiceIds" type="checkbox" /></td>
</tr>
}
</table>
</div>
<input type="button" value="Submit" onclick="return ChoicesPoster.passChoices()"
</div>
}
Я модифицировал ответ Оливера , который предложил алгоритмы расстояния Левенштейна, что здесь не лучший выбор, поскольку рассчитанное расстояние велико, когда были введены только части имен. Итак, я закончил использование алгоритма Longest Common Subsequence , реализованного с помощью awesome FuzzyString Lib .
const int TOLERANCE = 1;
string userInput = textInput.Text.ToLower();
var matchingPeople = people.Where(p =>
{
//Check Contains
bool contains = p.Name.ToLower().Contains(userInput);
if(contains) return true;
//Check LongestCommonSubsequence
bool subsequenceTolerated = p.Name.LongestCommonSubsequence(userInput).Length >= userInput.Length - TOLERANCE;
return subsequenceTolerated;
}).ToList();
На других языках, таких как python, у нас есть классные материалы для обработки текста, включая вычисления расстояния. Существуют некоторые алгоритмы, такие как Левенштейн, который вычисляет нечеткое расстояние между двумя строками. Я видел некоторые реализации в C # ( здесь ), а также еще один модуль был difflib, который доступен здесь . выходы этих алгоритмов являются числом. чем ближе к 0, тем лучше.
Вы пытались применить грубую силу? Самый простой способ - совместить строку поиска с подстроками целевых строк, начиная с начала, а затем выполнить самое близкое соответствие из всех совпадений.
Но это может быть неприемлемо из представления производительности.
Я сделал это сам до этого и начал с некоторых методов, перечисленных в wikipedia, приблизительной строки, соответствующей . Когда я закончил, я настроил свой алгоритм таким образом, который был не таким общим, но дал мне лучшие совпадения в моем домене.
Если ваш весь словарь находится в памяти и не слишком большой, вы можете просто применить вы сопоставляете алгоритм с каждым членом в словаре. Если ваш словарь большой, это, вероятно, будет чрезмерно использовать ваши ресурсы, и вам понадобится лучший алгоритм. Возможно, вы захотите также использовать функцию полнотекстового поиска вашей базы данных.
В моем случае я повторил, хотя каждая строка в моем словаре сравнивала «совпадающие прогоны», т. Е. 2 балла за совпадение в 2 символа , 3 для 3-х символов, совпадающих с 8 символами. Я побежал, несмотря на все возможные пары, тройки и т. Д. - забив каждую запись словаря и выбрав самый высокий результат подсчета очков. Толерантность опечаток, порядок слов и т. Д., Но дорогостоящий вычислительный - мой словарь составлял всего несколько тысяч фраз, поэтому для меня это очень хорошо работало. Это модифицированная версия коэффициента Dice.
У меня был проект для школы некоторое время назад, где у нас было текстовое поле, в котором ученики могли искать каждого сотрудника, учащегося, который имеет какое-то отношение к школе. Мы говорили о нескольких сотнях человек. Простой запрос Linq, который мы использовали, был невероятно быстрым на процессоре Core i3. Запрос вызывается каждый раз, когда пользователь вводит что-то в текстовое поле. В событии TextChanged мы вызывали запрос, который выглядел так:
var resultData = EmployeeList.Where(x=>x.Name.ToLower().Contains(textInput.Text.ToLower())).ToList();
Конечно, эта логика применяется только в том случае, если у вас есть «Dr. Martin Fowler» в одном свойстве или члене.
Возможно, вы могли бы использовать эту реализацию soundex: CodeProject . Что такое soundex, это сравнение двух строк и вычисление «произношение-подобия» в процентах. Некоторое время назад я строил поиск с помощью этой функции (встроенный PHP hasit)
Кажется, это работа для алгоритма расстояния Левенштейна ( одна из десятков реализаций C # ).
Вы даете этому алгоритму две строки (одну введенную пользователем и одну из вашего списка). Затем он вычисляет, сколько символов нужно заменить, добавить или удалить, чтобы перейти от первой строки ко второй. Затем вы можете взять все элементы из вашего списка, где расстояние меньше или равно трем (например), чтобы найти простые опечатки.
Если у вас есть этот метод, вы можете использовать его таким образом:
var userInput = textInput.Text.ToLower();
var matchingEmployees = EmployeeList.Where(x => x.Name.ToLower().Contains(userInput)
|| LevenshteinDistance.Compute(x.Name.ToLower(), userInput) <= 3)
.ToList();