Sauter la première colonne et se distinguer des autres
-
06-07-2019 - |
Question
Je dois sélectionner des lignes distinctes dans l'affichage de fichier texte ci-dessous.
FichierFichier
123| one| two| three <br/>
124| one| two| four <br/>
125| one |two| three <br/>
La sortie devrait ressembler à ceci
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 résoudre 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
La solution
L'espacement incertain dans la question n'aide pas ( en particulier autour du | deux |
, qui a un espacement différent du reste, ce qui implique que nous devons utiliser le rognage). , mais voici quelques méthodes LINQ personnalisées qui font le travail. J'ai utilisé le type anon purement comme moyen simple d'aplanir l'espacement incohérent (j'aurais aussi 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;
}
}
}
}
Autres conseils
Regardez ceci, cela fera 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 implémentez le IEqualityComparer de cette manière
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;
}
}
Cela vous donnera le résultat attendu.