Расширение StartsWith, которое ищет по всем словам

Существует ли расширение строки StartsWith, которое ищет в начале каждого слова в строке?

Что-то вроде: "Ben Stiller".StartsWithExtension("Sti") возвращает true

Я хочу это, чтобы я мог сделать предикат для поиска.

Допустим, есть список под названием "Люди". ICollection<Person>
У каждого человека есть свойство "Имя" со значениями, например, "Бен Стиллер" или "Адам Сэндлер".

Я хочу иметь возможность делать такие предикаты, как:

Persons.Where(p => p.Name.StartsWithExtension(query))

Спасибо (другие лучшие способы достижения этого приветствуются)


person sports    schedule 30.03.2013    source источник
comment
Если фамилия имеет собственное значение - в этом случае вы хотите искать/фильтровать по ней - имеет смысл разделить имя на 2 свойства - имя и фамилию (и, возможно, полное имя для удобной печати/регистрации или что бы вы ни делали с объектом человека)   -  person Honza Brestan    schedule 30.03.2013
comment
Что ж, самым простым (даже если и не самым лучшим) способом будет, наверное, Contains(" " + str);...   -  person Carsten    schedule 30.03.2013
comment
Вам нужно использовать это с Linq-to-Sql или Linq-to-Entities?   -  person p.s.w.g    schedule 30.03.2013
comment
@ p.s.w.g В любом случае, это не сработает: метод нельзя перевести в SQL. Он будет работать только в linq для объектов.   -  person Gert Arnold    schedule 30.03.2013
comment
Ответ @GertArnold AppDeveloper будет работать в SQL. Я пытаюсь точно определить, какой ответ ищет OP. Поскольку OP не указал никаких дополнительных ограничений, в большинстве ответов здесь предполагается, что строка уже находится в памяти.   -  person p.s.w.g    schedule 30.03.2013
comment
@ p.s.w.g Конечно, я понимаю, почему вы спрашиваете. Я неуклюже попытался сообщить ОП об ограничениях, дав понять, что это связано с вашим комментарием.   -  person Gert Arnold    schedule 30.03.2013
comment
Было бы здорово, если бы это работало в Linq-To-Sql из-за проблем с производительностью. Но поскольку я уже использую Linq-To-Entities, большинство приведенных здесь ответов великолепны.   -  person sports    schedule 31.03.2013


Ответы (4)


Вы можете сначала разбить строку по словам, например:

var result = "Ben Stiller".Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)
                          .Any(x => x.StartsWith("Sti"));

Конечно, вы можете написать это как собственный метод расширения, например:

public static bool AnyWordStartsWith(this string input, string test)
{
    return input.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)
                .Any(x => x.StartsWith(test));
}
person p.s.w.g    schedule 30.03.2013

Вероятно, наиболее кратким подходом является использование регулярных выражений:

public static bool StartsWithExtension(this string value, string toFind)
{
    return Regex.IsMatch(value, @"(^|\s)" + Regex.Escape(toFind));
}

Это также более надежно, чем разбиение исходной строки на символ ' ', поскольку он может обрабатывать другие символы пробела.

person JLRishe    schedule 30.03.2013
comment
Кроме того, с присущей регулярному выражению bcl псевдокэшностью вы можете увидеть прирост производительности при повторных запросах (хабар там) - person JerKimball; 31.03.2013

Почему бы вместо этого не создать метод «ToWords», а затем передать его результаты в StartsWith?

На самом деле, "ToWords" уже как бы существует:

Редактировать: для хихиканья, давайте поработаем над несколькими

 var someNames = new []{ "Sterling Archer", "Cyril Figgus" };
 var q = someNames
    .Select(name => name.Split(' '))
    .SelectMany( word => word)
     // the above chops into words
    .Where(word => word.StartsWith("Arch"));
person JerKimball    schedule 30.03.2013

Ну, вы даже можете проверить это так:

bool flag = (sample_str.StartsWith("Sti" ) || sample_str.Contains(".Sti") || sample_str.Contains(" Sti")) 
person Parimal Raj    schedule 30.03.2013