Ir primeira coluna e obter distinta de outras colunas
-
06-07-2019 - |
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
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.