Если я понимаю, о чем вы спрашиваете, это получение наименьшего индекса между индексами двух символов в строке, но проблема в том, что если существует только один из них, возвращается индекс другого, потому что он -1
.
Один из способов решить эту проблему - проверить наличие -1
в первой строке, а затем решить, что делать со второй:
public static int IndexOf (this string s, char a, char b) => s.IndexOf(a) == -1
// If it's not in 'a', return its index in 'b'
? s.IndexOf(b)
: s.IndexOf(b) == -1
// Else if it's not in 'b', return its index in 'a'
? s.IndexOf(a)
// Otherwise, return the smallest index between 'a' and 'b'
: Math.Min(s.IndexOf(a), s.IndexOf(b));
Однако, существует проблема с этим методом расширения !!
Поскольку существует неявное преобразование из char
в int
, этот метод будет скрыт собственной перегрузкой из метод IndexOf
, который принимает char
и int
, который возвращает «отсчитываемый от нуля индекс первого появления указанного символа, начиная с указанной позиции».
Я считаю, что это связано с тем, что собственные методы оцениваются и выбираются (если есть неявное совпадение) до оценки любых методов расширения, но я могу ошибаться.
Чтобы обойти эту проблему, мы можем просто дать у метода другое имя:
public static int IndexOfFirst (this string s, char a, char b) => s.IndexOf(a) == -1
? s.IndexOf(b)
: s.IndexOf(b) == -1
? s.IndexOf(a)
: Math.Min(s.IndexOf(a), s.IndexOf(b));
Кроме того, мы можем использовать аргумент params
, чтобы позволить этому методу обрабатывать 0
многие символы, из которых следует найти первый индекс:
public static int IndexOfFirst(this string s, params char[] args) =>
(args?.Any(arg => s.IndexOf(arg) > -1)).GetValueOrDefault()
? args.Select(arg => s.IndexOf(arg))
.Where(index => index > -1)
.Min()
: -1;