Pergunta

Digamos que eu tenha uma página da web que atualmente aceita um único valor de ID por meio de um parâmetro de URL:
http://example.com/mypage.aspx?ID=1234

Eu quero alterá-lo para aceitar um lista de ids, assim:
http://example.com/mypage.aspx?IDs=1234,4321,6789

Portanto, está disponível para o meu código como uma string via context.Request.QueryString["IDs"]. Qual é a melhor maneira de transformar esse valor de string em List<int>?

Editar: Eu sei como fazer .split() uma vírgula para obter uma lista de strings, mas pergunto porque não sei como converter facilmente essa lista de strings em uma lista int.Isso ainda está no .Net 2.0, então não há lambdas.

Foi útil?

Solução

Sem ofensa para aqueles que forneceram respostas claras, mas muitas pessoas parecem estar respondendo à sua pergunta em vez de abordar o seu problema.Você quer vários IDs, então acha que poderia fazer o seguinte:

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

O problema é que esta é uma solução não robusta.No futuro, se você quiser vários valores, o que fará se eles tiverem vírgulas?Uma solução melhor (e isso é perfeitamente válido em uma string de consulta) é usar vários parâmetros com o mesmo nome:

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

Então, qualquer analisador de string de consulta usado deverá ser capaz de retornar uma lista de IDs.Se não conseguir lidar com isso (e também lidar com ponto e vírgula em vez de e comercial), então está quebrado.

Outras dicas

Algo assim pode funcionar:

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;
}

O que seria então usado:

string intString = "1234,4321,6789";

IList<int> list = GetIdListFromString(intString);

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

Você pode instanciar um List<T> de um array.

VB.NET:

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

Isso está sujeito a erros de conversão se a matriz contiver elementos não-int

Tudo o que consigo pensar é percorrer a lista de strings (que você obteve ao realizar uma divisão) e fazer algo como int.TryParse() neles um após o outro e colocando-os em um novo List<int>.Encapsule-o em um pequeno método auxiliar em algum lugar e não será tão horrível.

Se você gosta do estilo funcional, você pode tentar algo como

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

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

Não há lambdas, mas você tem conversores e predicados e outras coisas interessantes que podem ser feitas a partir de métodos.

Eu vejo minha resposta chegou um pouco tarde, ou seja,vários outros escreveram o mesmo.Portanto apresento um método alternativo usando expressões regulares para validar e dividir a string.

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();
    }
}

Trecho de código final que leva o que espero ser o melhor de todas as sugestões:

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

Eu esperava poder fazer isso em uma ou duas linhas de código embutidas.Uma linha para criar a matriz de strings e, com sorte, encontrar algo na estrutura que eu ainda não conhecia para importar para um List<int> que pudesse lidar com a conversão de maneira inteligente.Mas se eu precisar mudar para um método, então o farei.E sim, estou usando VB.Eu apenas prefiro C# para fazer perguntas porque elas atrairão um público maior e sou igualmente fluente.

split é a primeira coisa que vem à mente, mas retorna um array, não uma lista;você poderia tentar algo como:


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

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

Você pode usar string.Split() para dividir os valores depois de extraí-los do URL.

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

Você apenas terá que procurar por eles e int.TryParse cada um deles.depois disso é só adicionar à lista.

Deixa pra lá - @Splash me venceu

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

Para completar, você desejará colocar try/catchs em torno do loop for (ou em torno da chamada int.Parse()) e tratar o erro com base em seus requisitos.Você também pode fazer um tryparse() assim:

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

Para continuar com a resposta anterior, simplesmente iterando pelo array retornado por Split e convertendo para um novo array de inteiros.Este exemplo abaixo em 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]);
        }

Acho que a maneira mais fácil é dividir como mostrado antes, percorrer os valores e tentar converter para 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;
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top