Пропустите первый столбец и получите отличие от других столбцов

StackOverflow https://stackoverflow.com/questions/1628853

Вопрос

Мне нужно выбрать отдельные строки из текстового файла, отображаемого ниже.

Текстовый файл

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

Результат должен выглядеть следующим образом

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

или

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

Я использую этот код для решения этой проблемы

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

Спасибо

Это было полезно?

Решение

Нечеткий интервал в вопросе не помогает (особенно вокруг |two|, который имеет интервал, отличный от остальных, подразумевая, что нам нужно использовать обрезку), но вот некоторые пользовательские методы LINQ, которые выполняют эту работу.Я использовал тип anon исключительно как простой способ сгладить несогласованный интервал (я мог бы также перестроить строку, но это показалось ненужным)

Обратите внимание, что без нечетного интервала это может быть просто:

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

Полный код:

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

Другие советы

Проверьте это, это сделает то, что вы хотите сделать

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

И внедрить Сравнитель IEqualityComparer вот так

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

}

Это даст вам результат, как вы и ожидали.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top