跳过第一列并与其他列区分开来

时间:2009-10-27 05:02:14

标签: linq distinct text-files skip

我需要从下面的Textfile显示中选择不同的行。

TextFile

 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/>

OR

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

由于

2 个答案:

答案 0 :(得分:1)

问题中不清楚的间距没有帮助(特别是围绕|two|,其间距与其余部分不同,这意味着我们需要使用修剪),但这里有一些习惯完成工作的LINQ方法。我使用anon-type纯粹作为一种简单的方法来消除不一致的间距(我也可以重建一个字符串,但似乎没必要)

请注意,如果没有奇数间距,可以简单地说:

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

答案 1 :(得分:0)

看看这个,这将做你想做的事情

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

}

它会按预期给你输出。