C# LINQ在List中查找重复项并删除一个

ktecyv1j  于 2022-12-06  发布在  C#
关注(0)|答案(2)|浏览(148)

如何从下面的列表中查找重复的项目并删除一个?

var mylist = new List<string>(){
   "itemA.config",
   "itemA.en-us.config",
   "itemB.config",
   "itemC.config", 
   "itemC.en-us.config",
   "itemC.fa-ir.config"
};

如果它的值为“*.fa-ir.config”,则保留它。否则,保留 *.config

var mylist = new List<string>(){
   "itemA.config",
   "itemB.config",
   "itemC.fa-ir.config"
};
osh3o9ms

osh3o9ms1#

你可以GroupBy(按ItemAItemB等)然后分析每组:

var mylist = mylist
  .GroupBy(item => item.Substring(0, item.IndexOf('.')))
  .Select(group => group.FirstOrDefault(item => item.EndsWith(".fa-ir.config")) 
                ?? group.FirstOrDefault(item => item.EndsWith(".config"))
                ?? group.First())
  .ToList();
ecbunoof

ecbunoof2#

我想这就是你的逻辑:DEMO解释如下

mylist = mylist 
    .Select(s => (Name:s, Culture:GetConfigCulture(s, out string[] tokens), Tokens:tokens))
    .GroupBy(x => x.Tokens.First(), StringComparer.InvariantCultureIgnoreCase)
    .Select(g => g.OrderBy(x => GetOrder(x.Culture)).First().Name)
    .ToList();

string GetConfigCulture(string name, out string[] tokens)
{
    tokens = name.Split('.');
    if(tokens.Length < 3) return null;
    return tokens[1];
}

int GetOrder(string culture)
{
    if(StringComparer.InvariantCultureIgnoreCase.Equals(culture, "fa-ir")) return 0;
    if(StringComparer.InvariantCultureIgnoreCase.Equals(culture, null)) return 1;
    return 2;
}

因此,您需要根据配置名称/路径的第一个标记删除重复项。如果存在特定于区域性的标记和一个“全局”标记,则您需要采用不带区域性的标记。如果它具有"fa-ir"区域性,则它具有优先级,并且应该采用。
因此,您需要按第一个进行分组,然后按此逻辑对每组中的项目进行排序,最后取第一个以删除其他重复项。

相关问题