IComparer для строки, которая проверяет, начинается ли x с y
У меня есть массив строк, и мне нужно получить все строки, которые начинаются с некоторого префикса. Я хочу использовать Array.BinarySearch(). Является ли это возможным? И как мне написать компаратор, если так?
2 ответа
Нет, вы не можете использовать BinarySearch
в этом случае. Вы могли бы использовать Enumerable.Where
вместо:
Dim query = From str In array Where str.StartsWith("prefix")
или с ( некрасиво в VB.NET) методом synatx:
query = array.Where(Function(str) str.StartsWith("prefix"))
Редактировать: упс, C#
var query = array.Where(s => s.StartsWith("prefix"));
использование ToArray
если вы хотите создать новый фильтрованный массив.
Создать собственный StartsWithComparer легко:
class StartsWithComparer : IComparer<string>
{
public int Compare(string a, string b) {
if(a.StartsWith(b)) {
return 0;
}
return a.CompareTo(b);
}
}
Как отмечали другие, это вернет только один индекс. У вас может быть пара помощников для возврата всех предметов:
IEnumerable<string> GetBefore(IList<string> sorted, int foundIndex, string prefix) {
for(var i = foundIndex - 1; i >= 0; i--) {
if(sorted[i].StartsWith(prefix)) {
yield return sorted[i];
}
}
}
IEnumerable<string> GetCurrentAndAfter(IList<string> sorted, int foundIndex, string prefix) {
for(var i = foundIndex; i < sorted.Count; i++) {
if(sorted[i].StartsWith(prefix)) {
yield return sorted[i];
}
}
}
Тогда использовать это:
var index = sorted.BinarySearch("asdf", new StartsWithComparer());
var previous = GetBefore(sorted, index, "asdf");
var currentAndAfter = GetCurrentAndAfter(sorted, index, "asdf");
Вы можете обернуть все это в свой собственный класс с помощью одного метода, который возвращает все элементы, которые начинаются с вашего префикса.