Получить строку из массива или установить значение по умолчанию в одну строку

Таким образом, у нас есть ?? для анализа его правого значения, когда левая рука равна нулю. Что является эквивалентом для string[].

Например,

string value = "One - Two"
string firstValue = value.Split('-')[0] ?? string.Empty;
string secondValue = value.Split('-')[1] ?? string.Empty;

Приведенный выше пример все равно потерпит крах, если мы попытаемся получить третий индекс или если string value = "One". Потому что это не ноль, а IndexOutOfRangeException выбрасывается.

https://docs.microsoft.com/en-us/dotnet/api/system.indexoutofrangeexception

Итак, что такое однострочное решение для решения вышеуказанной проблемы? Я хотел бы избежать сценария try-catch, потому что это дает ужасный код.

Я хочу получить значение из string[] с string.Empty в качестве резервного значения, поэтому мой string никогда не будет null.

Ответы

Ответ 1

Ну, вы можете попробовать Linq:

using System.Linq;

...

string thirdValue = value.Split('-').ElementAtOrDefault(2) ?? string.Empty;

Однако у вашего кода есть недостаток: у вас постоянно Split одна и та же строка. Я предлагаю извлечь value.Split('-'):

string value = "One - Two"
var items = value.Split('-');

string firstValue = items.ElementAtOrDefault(0) ?? string.Empty;
string secondValue = items.ElementAtOrDefault(1) ?? string.Empty;

Ответ 2

Я предлагаю вам создать метод для этого. который будет принимать два ввода типа string (представляющего входную строку) и целого числа (представляет указанный индекс), и должен возвращать значение разделения, если указанный индекс доступен, иначе он возвратит пустую строку:

string GetSubstring(string input, int index)
{
    string returnValue = String.Empty;
    string[] substrings = input.Split(new[] { "-" }, StringSplitOptions.RemoveEmptyEntries);
    returnValue = substrings.Length > index ? substrings[index] : returnValue;
    return returnValue;
}

Вот рабочий пример для вашей справки

Ответ 3

Может быть, следующий код будет полезен

string value = "One - Two";
string firstValue = (value.Split('-').Length == 1 ? value.Split('-')[0] : null) ?? string.Empty;
string secondValue = (value.Split('-').Length == 2 ? value.Split('-')[1] : null) ?? string.Empty;

Ответ 4

Одним из способов достижения этого является использование MoreLinqLead и деструктуризация кортежей:

string value = "One - Two";
var (first, second) = value.Split('-').Lead(1, string.Empty, (x, y) => (x, y)).First();

Или, если вы хотите более общий подход, который работает для всех индексов:

string value = "One - Two - Three - Fourth - Fifth";
var (first, second) = value.Split('-').Skip(6).Concat(string.Empty).Lead(7, string.Empty, (x, y) => (x, y)).First();

Этот код получит седьмую и четырнадцатую записи (ни одна из которых не существует, поэтому string.Empty будет использоваться для обеих).

Другой вариант - назначить две разные переменные в одной строке кода:

string value = "One - Two";
var split = value.Split('-');
string first = split[0] ?? string.Empty, second = split.ElementAtOrDefault(1) ?? string.Empty;

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

Обратите внимание, что нет необходимости использовать ElementOrDefault(0) - лучше использовать [0], поскольку Split никогда не будет возвращать массив без элементов.

Другой вариант - использовать деструктуризацию, но это действительно полезно только в том случае, если вас интересуют непрерывные записи в начале массива (хотя можно просто настроить параметры индекса разумно просто):

public static void Destructure<T>(this T[] items, T defaultValue, out T t0, out T t1)
{
    t0 = items.Length > 0 ? items[0] : defaultValue;
    t1 = items.Length > 1 ? items[1] : defaultValue;
}