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");

Вы можете обернуть все это в свой собственный класс с помощью одного метода, который возвращает все элементы, которые начинаются с вашего префикса.

Другие вопросы по тегам