删除列表中包含相同内容的行

时间:2011-09-13 22:27:01

标签: c# list duplicates

我有一个包含以下内容的列表:

C12 0402 123456 90
C133 0402 123456 90
C9 0402 123456 90
C132 0603 abcd 0
C54 0603 abcd 0
R FID1 fiducial 0
R FID2 fiducial 0
R FID3 fiducial 0
R FID4 fiducial 0

我想检查列表中的每一行,并确保没有添加重复项...我试过这个,但我知道这里有一个逻辑错误。

List<string> noDuplicatesList = new List<string>();

foreach (var line in theList)
{
    if (!noDuplicatesList.Contains(line.PartNumber)) //This is doing nothing...?
        noDuplicatesList.Add(line.Name + " " + line.PartDescription + " " line.PartNumber + " " + line.Rotation);
}

foreach (var line in noDuplicatesList)
{
    var splitLine = line.Split(' ');
    //Print out statements...
}

问题

如何删除/跳过包含相同值的行(在上面的示例123456abcdfiducial中),以便它只打印如下内容:

C12 0402 123456 90
C132 0603 abcd 0
R FID1 fiducial 0

2 个答案:

答案 0 :(得分:3)

您是否只使用第3列作为分组条件?

var noDuplicatesList = lines
    .GroupBy(l => l.PartNumber)
    .Select(group => group.First())

foreach(var item in noDuplicatesList)
    Console.WriteLine("{0} {1} {2} {3}", 
        item.Name,
        item.PartDescription,
        item.PartNumber,
        item.Rotation
    );

lines:

C12 0402 123456 90
C133 0402 123456 90
C9 0402 123456 90
C132 0603 abcd 0
C54 0603 abcd 0
R FID1 fiducial 0
R FID2 fiducial 0
R FID3 fiducial 0
R FID4 fiducial 0

lines.GroupBy(l => l.PartNumber):

{ C12 0402 123456 90, C133 0402 123456 90, C9 0402 123456 90}
{ C132 0603 abcd 0, C54 0603 abcd 0 }
{ R FID1 fiducial 0, R FID2 fiducial 0, R FID3 fiducial 0, R FID4 fiducial 0 }

lines.GroupBy(l => l.PartNumber).Select(group => group.First()):

C12 0402 123456 90
C132 0603 abcd 0
R FID1 fiducial 0

答案 1 :(得分:0)

(经过反思,这个答案假设您的列表中的订单计数。如果订单无关紧要,那么只需使用下面答案中引用的GroupBy。)

实现此目的的典型“模块化”方法是编写一个类似于此的PartitionBy函数:

private static IEnumerable<ICollection<T>> PartitionBy<T, U>(
    IEnumerable<T> sequence, Func<T, U> selector)
{
    var buffer = new List<T>();

    using (var e = sequence.GetEnumerator())
    {
        if (!e.MoveNext())
            yield break;

        var priorValue = selector(e.Current);
        buffer.Add(e.Current);

        while (e.MoveNext())
        {
            var newValue = selector(e.Current);

            if (!object.Equals(selector(e.Current), priorValue))
            {
                priorValue = newValue;
                yield return buffer;
                buffer = new List<T>();
            }

            buffer.Add(e.Current);
        }
    }

    if (buffer.Any())
        yield return buffer;
}

然后你的问题可以这样解决:

var results = PartitionBy(objs, x => /* ... */).Select(list => list.First());

然而,...是您从列表中的对象中获取第三个值(例如x.Split()[2]。)