从已排序列表中删除重复项 c#

3

我有一个关于大量文件的详细列表。该列表包括文件ID、上次修改日期和文件路径。问题是,有些文件存在重复,这些重复的文件是旧版本,并且有时具有不同的文件路径。我想只保留最新版本的文件,而不考虑文件路径。因此,我创建了一个循环来遍历排序后的列表,检查ID是否唯一,如果唯一,则存储在一个新的唯一列表中。

 var ordered = list.OrderBy(x => x.ID).ThenByDescending(x => x.LastModifiedDate);

            List<Item> unique = new List<Item>();

            string curAssetId = null;

            foreach (Item result in ordered)
            {
                if (!result.ID.Equals(curAssetId))
                {
                    unique.Add(result);
                    curAssetId = result.ID;
                }
            }

然而,这仍然允许重复项进入数据库,我无法弄清楚为什么这段代码不能像预期的那样工作。所谓的重复是指文件具有相同的ID但具有不同的文件路径,就像我之前说过的那样,这不应该是一个问题。我只想要最新版本,无论路径如何。还有其他人能看出问题在哪里吗?谢谢

   var ordered = listOfItems.OrderBy(x => x.AssetID).ThenByDescending(x => x.LastModifiedDate);
            List<Item> uniqueItems = new List<Item>();

            foreach (Item result in ordered)
            {
                if (!uniqueItems.Any(x => x.AssetID.Equals(result.AssetID)))
                {
                    uniqueItems.Add(result);

                }
            } 

这是我现在拥有的,但它仍然允许重复。



你的 LastModifiedDate 的确切值是多少?这个 date 是否包含 hour:mm:ss - spajce
是的,那就是格式。 - RebeccaD
尝试使用.Distinct获取没有hour:mm:ss的确切日期值。你能试试我的答案吗? - spajce
5个回答

3
这是因为你没有搜索整个列表来检查ID是否唯一。
List<Item> unique = new List<Item>();

        string curAssetId = null; // here is the problem 

        foreach (Item result in ordered)
        {
            if (!result.ID.Equals(curAssetId)) // here you only compare the last value.
            {
                unique.Add(result);
                curAssetId = result.ID; // You are only assign the current ID value and 
            }
        }

为了解决这个问题,需要更改以下内容。
     if (!result.ID.Equals(curAssetId)) // here you only compare the last value.
        {
            unique.Add(result);
            curAssetId = result.ID; // You are only assign the current ID value and 
        }

to

if (!unique.Any(x=>x.ID.Equals(result.ID))) 
        {
            unique.Add(result);

        }

这个方法出现了重复的情况,不知道还有什么其他的问题。谢谢。 - RebeccaD
我不相信,只是修改了答案部分的内容。 - TalentTuner
我在上面添加了我现在程序中拥有的内容,但它仍然允许重复。这非常奇怪。 - RebeccaD
有其他事情正在发生,我确信上述去重ID的更正方法会奏效,它只是检查唯一列表中是否存在当前ID的任何项。 - TalentTuner
感谢您的帮助。经过一些调查,我意识到我的多线程添加列表的方式存在问题,所以我进行了更改,现在似乎已经可以正常工作了! - RebeccaD

2

我不知道这段代码是否只是简化过的,但你是否考虑过按照ID分组、按照LastModifiedDate排序,然后仅取每个组中的第一个呢?

类似于以下的代码:

var unique = list.GroupBy(i => i.ID).Select(x => x.OrderByDescending(y => y.LastModifiedDate).First());

我尝试了这种方法,但仍然保存了重复项。似乎不合理,它仍然发生了。 - RebeccaD
你确定你的列表包含了所有的项目吗?如果你没有处理完整个列表,你将会得到重复的ID。 - James Osborn
这个答案非常完美,解决了我的一个问题。我想按照ID对记录进行分组,然后在每个组内进行排序,并且只获取每个组的第一条记录,最终将它们合并成一个可枚举对象。谢谢。 - Klaw

1

var ordered = list.OrderBy(x => x.ID).ThenByDescending(x => x.LastModifiedDate).Distinct() 是什么意思?


0
为此,您必须创建自己的EquityComparer,之后您可以使用linq的Distinct方法。在msdn上的Enumerable.Distinct 另外,我认为您可以保留当前的代码,但必须以这样的方式进行修改(作为示例):
    var ordered = list.OrderByDescending(x => x.LastModifiedDate);
    var unique = new List<Item>();

    foreach (Item result in ordered)
    {
        if (unique.Any(x => x.ID == result.ID))
            continue;
        unique.Add(result);
    }

0
List<Item> p = new List<Item>();
var x = p.Select(c => new Item
     {
         AssetID = c.AssetID,
         LastModifiedDate = c.LastModifiedDate.Date
     }).OrderBy(y => y.id).ThenByDescending(c => c.LastModifiedDate).Distinct();

问题在于程序要求日期中包含时间。我尝试了答案,但现在没有记录被返回。 - RebeccaD
请在.Distinct()之后使用.ToList(),即.Distinct().ToList();。 - spajce

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接