使用 Linq 在列表中查找重复项

发布于 2024-11-04 02:32:48 字数 1258 浏览 1 评论 0原文

我正在建立一个用户列表。每个用户都有一个全名。 我正在比较 FullName 上的用户。

我正在从旧数据库中获取包含用户的数据表,并将它们解析为“用户”对象。并将它们添加到 List 中。代码中是一个 List

它是这样的:

    List<Deelnemer> tempDeeln = new List<Deelnemer>();
    bool dupes = false;
    foreach (DataRow rij in deeln.Rows) {
            Deelnemer dln = new Deelnemer();
            dln.Dln_Creatiedatum = DateTime.Now;
            dln.Dln_Email = rij["Ler_Email"].ToString();
            dln.Dln_Inst_ID = inst.Inst_ID;
            dln.Dln_Naam = rij["Ler_Naam"].ToString();
            dln.Dln_Username = rij["LerLog_Username"].ToString();
            dln.Dln_Voornaam = rij["Ler_Voornaam"].ToString();
            dln.Dln_Update = (DateTime)rij["Ler_Update"];
            if (!dupes && tempDeeln.Count(q => q.FullName.ToLower() == dln.FullName.ToLower()) > 0)
                dupes = true;
            tempDeeln.Add(dln);
     }

然后当 foreach 完成时,我查看 bool 是否为 true,检查哪些是双打,并删除最旧的。

现在,我认为这部分代码非常糟糕:

     if (!dupes && tempDeeln.Count(q => q.FullName.ToLower() == dln.FullName.ToLower()) > 0)

它为每个添加的用户运行,并运行所有已创建的用户。

我的问题:我将如何优化它。

I am building a list of Users. each user has a FullName.
I'm comparing users on FullName.

i'm taking a DataTable with the users from the old DB and parsing them to a 'User' Object. and adding them in a List<Users>. which in the code is a List<Deelnemer>

It goes like this:

    List<Deelnemer> tempDeeln = new List<Deelnemer>();
    bool dupes = false;
    foreach (DataRow rij in deeln.Rows) {
            Deelnemer dln = new Deelnemer();
            dln.Dln_Creatiedatum = DateTime.Now;
            dln.Dln_Email = rij["Ler_Email"].ToString();
            dln.Dln_Inst_ID = inst.Inst_ID;
            dln.Dln_Naam = rij["Ler_Naam"].ToString();
            dln.Dln_Username = rij["LerLog_Username"].ToString();
            dln.Dln_Voornaam = rij["Ler_Voornaam"].ToString();
            dln.Dln_Update = (DateTime)rij["Ler_Update"];
            if (!dupes && tempDeeln.Count(q => q.FullName.ToLower() == dln.FullName.ToLower()) > 0)
                dupes = true;
            tempDeeln.Add(dln);
     }

then when the foreach is done, i look if the bool is true, check which ones are the doubles, and remove the oldest ones.

now, i think this part of the code is very bad:

     if (!dupes && tempDeeln.Count(q => q.FullName.ToLower() == dln.FullName.ToLower()) > 0)

it runs for every user added, and runs over all the already created users.

my question: how would I optimize this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

调妓 2024-11-11 02:32:48

您可以使用诸如 HashSet 之类的集合 跟踪迄今为止观察到的唯一名称。哈希集支持恒定时间插入和查找,因此与现有解决方案不同,不需要对每个新项目进行完整的线性搜索。

var uniqueNames = new HashSet<string>(StringComparer.CurrentCultureIgnoreCase);
...

foreach(...)
{
   ...

   if(!dupes)
   {
       // Expression is true only if the set already contained the string.
       dupes = !uniqueNames.Add(dln.FullName); 
   }
}

如果您想在组装列表(不使用哈希集)之后“删除”重复项(即为每个名称生成一个代表元素),您可以执行以下操作:

var distinctItems = tempDeeln.GroupBy(dln => dln.FullName, 
                                        StringComparer.CurrentCultureIgnoreCase)
                             .Select(g => g.First());

You can use a set such as a HashSet<T> to track unique names observed so far. A hash-set supports constant-time insertion and lookup, so a full linear-search will not be required for every new item unlike you exising solution.

var uniqueNames = new HashSet<string>(StringComparer.CurrentCultureIgnoreCase);
...

foreach(...)
{
   ...

   if(!dupes)
   {
       // Expression is true only if the set already contained the string.
       dupes = !uniqueNames.Add(dln.FullName); 
   }
}

If you want to "remove" dupes (i.e. produce one representative element for each name) after you have assembled the list (without using a hash-set), you can do:

var distinctItems = tempDeeln.GroupBy(dln => dln.FullName, 
                                        StringComparer.CurrentCultureIgnoreCase)
                             .Select(g => g.First());
辞别 2024-11-11 02:32:48

计数将遍历整组项目。尝试使用 Any,这样它只会检查该项目的第一次出现。

if (!dupes && tempDeeln.Any(q => q.FullName.ToLower() == dln.FullName.ToLower()))
            dupes = true;

Count will go through whole set of items. Try to use Any, this way it will only check for first occurrence of the item.

if (!dupes && tempDeeln.Any(q => q.FullName.ToLower() == dln.FullName.ToLower()))
            dupes = true;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文