Вопрос

Допустим, у меня есть веб-страница, которая в данный момент принимает единственное значение ID через параметр url:
http://example.com/mypage.aspx?ID=1234

Я хочу изменить его, чтобы принять Список из идентификаторов, подобных этому:
http://example.com/mypage.aspx?IDs=1234 ,4321,6789

Таким образом, он доступен для моего кода в виде строки через контекст.Запрос.Строка запроса["Идентификаторы"]. Каков наилучший способ превратить это строковое значение в список<int>?

Редактировать: Я знаю, как сделать .split() через запятую, чтобы получить список строк, но я спрашиваю, потому что я не знаю, как легко преобразовать этот список строк в список int.Это все еще в .Net 2.0, так что никаких лямбд.

Это было полезно?

Решение

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

http://example.com/mypage.aspx?IDs=1234 ,4321,6789

Проблема в том, что это ненадежное решение.В будущем, если вам понадобится несколько значений, что вы будете делать, если в них будут запятые?Лучшим решением (и это вполне допустимо в строке запроса) является использование нескольких параметров с одинаковым именем:

http://example.com/mypage.aspx?ID=1234 ;ID=4321;ID=6789

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

Другие советы

Что-то вроде этого могло бы сработать:

public static IList<int> GetIdListFromString(string idList)
{
    string[] values = idList.Split(',');

    List<int> ids = new List<int>(values.Length);

    foreach (string s in values)
    {
        int i;

        if (int.TryParse(s, out i))
        {
            ids.Add(i);
        }
    }

    return ids;
}

Который затем будет использован:

string intString = "1234,4321,6789";

IList<int> list = GetIdListFromString(intString);

foreach (int i in list)
{
    Console.WriteLine(i);
}

Вы можете создать экземпляр списка<T> из массива.

VB.NET:

Dim lstIDs as new List(of Integer)(ids.split(','))

Это может привести к ошибкам приведения, хотя, если массив содержит элементы, отличные от int

Все, о чем я могу думать, это перебрать список строк (который вы получили в результате выполнения разделения) и сделать что-то вроде int.TryParse() на них один за другим и помещая их в новый List<int>.Инкапсулируйте это где-нибудь в симпатичном маленьком вспомогательном методе, и это не будет слишком ужасно.

Если вам нравится функциональный стиль, вы можете попробовать что-то вроде

    string ids = "1,2,3,4,5";

    List<int> l = new List<int>(Array.ConvertAll(
        ids.Split(','), new Converter<string, int>(int.Parse)));

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

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

class Program
{
    //Accepts one or more groups of one or more digits, separated by commas.
    private static readonly Regex CSStringPattern = new Regex(@"^(\d+,?)*\d+$");

    //A single ID inside the string. Must only be used after validation
    private static readonly Regex SingleIdPattern = new Regex(@"\d+");

    static void Main(string[] args)
    {
        string queryString = "1234,4321,6789";

        int[] ids = ConvertCommaSeparatedStringToIntArray(queryString);
    }

    private static int[] ConvertCommaSeparatedStringToIntArray(string csString)
    {
        if (!CSStringPattern.IsMatch(csString))
            throw new FormatException(string.Format("Invalid comma separated string '{0}'",
                                                    csString));

        List<int> ids = new List<int>();
        foreach (Match match in SingleIdPattern.Matches(csString))
        {
            ids.Add(int.Parse(match.Value)); //No need to TryParse since string has been validated
        }
        return ids.ToArray();
    }
}

Окончательный фрагмент кода, который, я надеюсь, является лучшим из всех предложенных:

Function GetIDs(ByVal IDList As String) As List(Of Integer)
    Dim SplitIDs() As String = IDList.Split(new Char() {","c}, StringSplitOptions.RemoveEmptyEntries)
    GetIDs = new List(Of Integer)(SplitIDs.Length)
    Dim CurID As Integer
    For Each id As String In SplitIDs
        If Integer.TryParse(id, CurID) Then GetIDs.Add(CurID)
    Next id
End Function

Я надеялся, что смогу сделать это в одной или двух строках встроенного кода.Одна строка, чтобы создать массив строк и, надеюсь, найти что-то во фреймворке, чего я еще не знал, для обработки импорта этого в список<int> , который мог бы разумно обрабатывать приведение.Но если мне нужно перенести это в какой-то метод, то я это сделаю.И да, я использую VB.Я просто предпочитаю C # для того, чтобы задавать вопросы, потому что они привлекут большую аудиторию, а я говорю примерно так же свободно.

разделение - это первое, что приходит на ум, но это возвращает массив, а не список;вы могли бы попробовать что-то вроде:


List<int> intList = new List<int>;

foreach (string tempString in ids.split(',')
{
    intList.add (convert.int32(tempString));
}

Вы можете использовать string .Split() для разделения значений после их извлечения из URL.

string[] splitIds = ids.split(',');

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

Неважно - @Splash опередил меня в этом

List<int> convertIDs = new List<int>;
string[] splitIds = ids.split(',');
foreach(string s in splitIds)
{
    convertIDs.Add(int.Parse(s));
}

Для полноты картины вам нужно будет поместить try / catches вокруг цикла for (или вокруг вызова int.Parse()) и обработать ошибку на основе ваших требований.Вы также можете выполнить функцию tryparse() следующим образом:

List<int> convertIDs = new List<int>;
string[] splitIds = ids.split(',');
foreach(string s in splitIds)
{
    int i;
    int.TryParse(out i);
    if (i != 0)
       convertIDs.Add(i);
}

Чтобы продолжить предыдущий ответ, достаточно просто выполнить итерацию по массиву, возвращаемому Split, и преобразовать в новый массив целых чисел.Этот пример ниже на языке C#:

        string[] splitIds = stringIds.Split(',');

        int[] ids = new int[splitIds.Length];
        for (int i = 0; i < ids.Length; i++) {
            ids[i] = Int32.Parse(splitIds[i]);
        }

Я думаю, что самый простой способ - это разделить, как показано ранее, а затем перебрать значения и попытаться преобразовать в int.

class Program
{
    static void Main(string[] args)
    {
        string queryString = "1234,4321,6789";

        int[] ids = ConvertCommaSeparatedStringToIntArray(queryString);
    }

    private static int[] ConvertCommaSeparatedStringToIntArray(string csString)
    {
        //splitting string to substrings
        string[] idStrings = csString.Split(',');

        //initializing int-array of same length
        int[] ids = new int[idStrings.Length];

        //looping all substrings
        for (int i = 0; i < idStrings.Length; i++)
        {
            string idString = idStrings[i];

            //trying to convert one substring to int
            int id;
            if (!int.TryParse(idString, out id))
                throw new FormatException(String.Format("Query string contained malformed id '{0}'", idString));

            //writing value back to the int-array
            ids[i] = id;
        }

        return ids;
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top