Pergunta

Eu preciso selecionar linhas distintas de exibição Textfile abaixo.

TextFile

 123| one| two| three  <br/>
124| one| two| four <br/>
 125| one |two| three <br/>

saída deve gostar deste

 123| one| two| three  <br/>
124| one| two| four <br/>

ou

124| one| two| four <br/>
125| one |two| three <br/>

Eu estou usando este código para trabalhar fora este problema

var readfile = File.ReadAllLines(" text file location ");
        var spiltfile = (from f in readfile
                    let line = f.Split('|')
                    let y = line.Skip(1)
                    select (from str in y
                            select str).FirstOrDefault()).Distinct()

Graças

Foi útil?

Solução

O espaçamento claro na pergunta não ajuda ( especialmente em torno da |two|, que tem espaçamento diferente do que o resto, o que implica que precisamos usar o corte), mas aqui está alguns métodos LINQ personalizada que fazer o emprego. Eu usei o tipo Anon puramente como uma maneira simples de achatando o espaçamento inconsistente (Eu também poderia ter reconstruído uma corda, mas parecia desnecessário)

Note que sem o espaçamento estranho, isso pode ser simplesmente:

var qry = ReadLines("foo.txt")
        .DistinctBy(line => line.Substring(line.IndexOf('|')));

código completo:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
static class Program
{
    static void Main()
    {
        var qry = (from line in ReadLines("foo.txt")
                   let parts = line.Split('|')
                   select new
                   {
                       Line = line,
                       Key = new
                       {
                           A = parts[1].Trim(),
                           B = parts[2].Trim(),
                           C = parts[3].Trim()
                       }
                   }).DistinctBy(row => row.Key)
                  .Select(row => row.Line);

        foreach (var line in qry)
        {
            Console.WriteLine(line);
        }
    }
    static IEnumerable<TSource> DistinctBy<TSource, TValue>(
        this IEnumerable<TSource> source,
        Func<TSource, TValue> selector)
    {
        var found = new HashSet<TValue>();
        foreach (var item in source)
        {
            if (found.Add(selector(item))) yield return item;
        }
    }
    static IEnumerable<string> ReadLines(string path)
    {
        using (var reader = File.OpenText(path))
        {
            string line;
            while ((line = reader.ReadLine()) != null)
            {
                yield return line;
            }
        }
    }
}

Outras dicas

Confira este, isso vai fazer o que você quer fazer

    static void Main(string[] args)
    {


        string[]  readfile = System.IO.File.ReadAllLines(@"D:\1.txt");
        var strList = readfile.Select(x => x.Split('|')).ToList();            

        IEnumerable<string[]> noduplicates =strList.Distinct(new StringComparer());

        foreach (var res in noduplicates)
            Console.WriteLine(res[0] + "|" + res[1] + "|" + res[2] + "|" + res[3]);
     }

E implementar o IEqualityComparer Desta forma

class StringComparer : IEqualityComparer<string[]>
{
    public bool Equals(string[] x, string[] y)
    {         
        if (Object.ReferenceEquals(x, y)) return true;

        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        return x[1].Trim() == y[1].Trim() && x[2].Trim() == y[2].Trim() && x[3].Trim() == y[3].Trim() ;
    }


    public int GetHashCode(string[] data)
    {

        if (Object.ReferenceEquals(data, null)) return 0;        
        int hash1 = data[1] == null ? 0 : data[1].Trim().GetHashCode();

        int hash2 = data[2] == null ? 0 : data[2].Trim().GetHashCode();

        int hash3 = data[3] == null ? 0 : data[3].Trim().GetHashCode();

        return hash1 ^ hash2 * hash3;
    }

}

Ele vai dar u a saída como você esperava.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top