none
Extrair informações de um txt RRS feed

  • Pergunta

  • Boa tarde pessoal,

    Tenho um txt nesse formato:

    Gostaria de catar somente o valor maior da primeira para o mesmo valor da segunda, assim:

    3 1011

    4 2010

    1 1011 
    2 1011
    3 1011
    1 2010
    2 2010
    3 2010
    4 2010
    


    segunda-feira, 6 de julho de 2015 17:04

Respostas

  • Segue abaixo um pequeno exemplo.

        Dictionary<int, int> listaDeValores = new Dictionary<int, int>();
    
                    string line;
                    System.IO.StreamReader file = new System.IO.StreamReader(@"C:\Users\bruno.joaquim\Desktop\test.txt");
                    while ((line = file.ReadLine()) != null)
                    {
                        var indexDoEspacoEmBranco = line.IndexOf(' ');
                        var coluna1 = Convert.ToInt32(line.Substring(0, indexDoEspacoEmBranco));
                        var coluna2 = Convert.ToInt32(line.Substring(indexDoEspacoEmBranco, line.Length - 1));
    
                        if(!listaDeValores.ContainsKey(coluna2))
                        {
                            listaDeValores.Add(coluna2, coluna1);
                        }
                        else
                        {
                            var valorAtualNoDicionario = listaDeValores[coluna2];
    
                            if (coluna1 > valorAtualNoDicionario)
                                listaDeValores[coluna2] = coluna1;
                        }
                    }



    segunda-feira, 6 de julho de 2015 17:32

Todas as Respostas

  • Olá Marques, você gostaria de extrair o maior valor da primeira coluna e o maior valor da segunda?

    segunda-feira, 6 de julho de 2015 17:10
  • Olá Bruno, seria o maior valor da coluna 1 para mesmo valor da coluna 2.
    segunda-feira, 6 de julho de 2015 17:13
  • Você pode usar um dicionário para controlar o maior valor a cada linha que você lê do arquivo.

    Basicamente você armazena a informação da segunda coluna na key, e o valor da primeira informação no value.

    Cada linha que você ler do arquivo, você consulta o dicionario para ver se você já tem um item com o valor da segunda coluna, caso não tenha, você adiciona normalmente.

    Caso contrário, você consulta o valor lido da coluna 1 e compara com o que tem no dicionário, se o valor da linha lida for maior, você substitui no value da linha do dicionário.

    Após passar em todas as linhas, o seu dicionário vai ter armazenado o maior valor da primeira para cada valor da segunda.

    Espero ter ajudado.



    segunda-feira, 6 de julho de 2015 17:25
  • Segue abaixo um pequeno exemplo.

        Dictionary<int, int> listaDeValores = new Dictionary<int, int>();
    
                    string line;
                    System.IO.StreamReader file = new System.IO.StreamReader(@"C:\Users\bruno.joaquim\Desktop\test.txt");
                    while ((line = file.ReadLine()) != null)
                    {
                        var indexDoEspacoEmBranco = line.IndexOf(' ');
                        var coluna1 = Convert.ToInt32(line.Substring(0, indexDoEspacoEmBranco));
                        var coluna2 = Convert.ToInt32(line.Substring(indexDoEspacoEmBranco, line.Length - 1));
    
                        if(!listaDeValores.ContainsKey(coluna2))
                        {
                            listaDeValores.Add(coluna2, coluna1);
                        }
                        else
                        {
                            var valorAtualNoDicionario = listaDeValores[coluna2];
    
                            if (coluna1 > valorAtualNoDicionario)
                                listaDeValores[coluna2] = coluna1;
                        }
                    }



    segunda-feira, 6 de julho de 2015 17:32
  • Sim Bruno, funcionou, obrigado, adaptei o código abaixo:

    Mas tem um porém, como o txt tem mais de 40mil linhas o processo demora um pouco, há como otimizar? Será que salvar tudo no dicionário para depois pesquisar ficaria mais rápido? Você teria alguma sugestão?

        Private Shared Function InlineAssignHelper(Of T)(ByRef target As T, ByVal value As T) As T
            target = value
            Return value
        End Function
    
            Dim listaDeValores As New Dictionary(Of Integer, Integer)()
    
            Dim line As String
            Dim file As New System.IO.StreamReader("C:\teste.txt")
            While (InlineAssignHelper(line, file.ReadLine())) IsNot Nothing
                Dim indexDoEspacoEmBranco = line.IndexOf(" "c)
                Dim coluna1 = Convert.ToInt32(line.Substring(0, indexDoEspacoEmBranco))
                Dim coluna2 = Convert.ToInt32(line.Substring(indexDoEspacoEmBranco, line.Length - 1))
    
                If Not listaDeValores.ContainsKey(coluna2) Then
                    listaDeValores.Add(coluna2, coluna1)
                Else
                    Dim valorAtualNoDicionario = listaDeValores(coluna2)
    
                    If coluna1 > valorAtualNoDicionario Then
                        listaDeValores(coluna2) = coluna1
                    End If
                End If
            End While
    
            DataGridView1.DataSource = listaDeValores.ToList

    segunda-feira, 6 de julho de 2015 17:55
  • Outra maneira que você poderia fazer é ao invés de fazer um dicionário int,int: tu pode fazer um dicionário int, List<int>,  assim você vai armazenando todos os valores da coluna 1 nessa lista, depois que você passou as 40.000 linhas você pega e usa a função Max para pegar o maior, não tenho certeza se vai melhorar muito o desempenho pois você vai estar usando List, mas não custa tentar, segue abaixo o código readaptado.

    Dictionary<int, List<int>> listaDeValores = new Dictionary<int, List<int>>();
    
                    string line;
                    System.IO.StreamReader file = new System.IO.StreamReader(@"C:\Users\bruno.joaquim\Desktop\test.txt");
                    while ((line = file.ReadLine()) != null)
                    {
                        var indexDoEspacoEmBranco = line.IndexOf(' ');
                        var coluna1 = Convert.ToInt32(line.Substring(0, indexDoEspacoEmBranco));
                        var coluna2 = Convert.ToInt32(line.Substring(indexDoEspacoEmBranco, line.Length - 1));
    
                        if (!listaDeValores.ContainsKey(coluna2))
                        {
                            listaDeValores.Add(coluna2, new List<int>() { coluna1 });
                        }
                        else
                        {
                            var valorAtualNoDicionario = listaDeValores[coluna2];
                            valorAtualNoDicionario.Add(coluna1);
                        }
                    }
    
                    foreach(var l in listaDeValores)
                    {
                        var maior = l.Value.Max();
                    }


    segunda-feira, 6 de julho de 2015 18:03