Domanda

Devo selezionare righe distinte dalla visualizzazione del file di testo di seguito.

File di testo

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

All'output dovrebbe piacere questo

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

OPPURE

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

Sto usando questo codice per risolvere questo 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()

Grazie

È stato utile?

Soluzione

La spaziatura poco chiara nella domanda non aiuta ( in particolare attorno al | two | , che ha una spaziatura diversa rispetto al resto, il che implica che dobbiamo usare il taglio) , ma ecco alcuni metodi LINQ personalizzati che fanno il lavoro. Ho usato il tipo anone semplicemente come un modo semplice per appiattire la spaziatura incoerente (avrei potuto anche ricostruire una stringa, ma sembrava inutile)

Nota che senza la spaziatura dispari, questo può essere semplicemente:

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

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

Altri suggerimenti

Dai un'occhiata, questo farà quello che vuoi fare

    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 implementa IEqualityComparer in questo modo

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

}

Ti darà l'output come ti aspettavi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top