2009-10-27 6 views
1

Je dois sélectionner des lignes distinctes dans l'affichage du fichier texte ci-dessous.Ignorer la première colonne et se distinguer des autres colonnes

TextFile

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

sortie doit aimer ce

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

OU

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

J'utilise ce code pour ce problème

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

Merci

+1

J'ai indenté les lignes d'échantillons "telles quelles", mais pourriez-vous clarifier l'espacement? En particulier: le dernier exemple inclut des espaces qui ne sont pas dans la source. –

Répondre

1

L'espacement pas clair dans la question ne vous aide pas (surtout autour du |two|, qui a un espacement différent que les autres, ce qui implique que nous devons utiliser la coupe), mais voici quelques méthodes LINQ personnalisées ça fait le boulot. J'ai utilisé le type anon purement comme un moyen simple d'aplatir l'espacement incohérent (j'aurais pu reconstruire une chaîne, mais cela semblait inutile)

Notez que sans l'espacement impair, cela peut être simplement:

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

code complet:

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

Vérifiez ce, cela va faire ce que vous voulez faire

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

et mettre en œuvre la IEqualityComparer cette façon

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

} 

Il va donner u la sortie comme prévu.

Questions connexes