【问题标题】:C# <LIST> How to check for non-unique values in the list?C# <LIST> 如何检查列表中的非唯一值?
【发布时间】:2021-08-09 08:05:13
【问题描述】:

这是构造函数(它是完整的,但这里我只显示第一行):

Public Class Player (string firstName, string lastName, string email)

程序:

Player player1 = new Player("Mike","Dalton", md@mail.com);
Player player2 = new Player("Mario","Davis", mdavis@mail.com);
Player player3 = new Player("Mia","Duncan", md@mail.com);
...

List<Player> players = new List<Player> { player1, player2, player3};

列表中有 3 名玩家。真正的清单很长。需要检查所有电子邮件地址是否都是唯一的。
(如您所见:email_player1 = email_player 3)

最后,一条简单的消息 (console.writeline) 应该说明是否有 email_doubles。

你能帮帮我吗?

【问题讨论】:

    标签: c# list collections iteration


    【解决方案1】:

    您可以尝试以下方法:

    List<string> emailList = players.Select(x => x.Email).ToList();
    if (emailList.Count > emailList.Distinct().Count())
    {
       Console.WriteLine("Duplicate email address found.");
    }
    

    如果您想专门显示重复的电子邮件地址,也可以尝试以下方法:

    var playersGroupByEmailList = players.GroupBy(x => x.Email).Select(g => new { Email = g.Key, Count = g.Count() });
    playersGroupByEmailList = playersGroupByEmailList.Where(x => x.Count > 1).ToList();
    if (playersGroupByEmailList.Any())
    {
       foreach (var playerGroupByEmail in playersGroupByEmailList)
       {
           Console.WriteLine($"{playerGroupByEmail.Email} is duplicate.");
       }
    }
    

    【讨论】:

    • var distinctPlayersCount = players.Select(player=&gt;player.Email).Distinct().Count() 会更好,因为它会在执行.Count() 时遍历列表一次
    • @Ramesh 感谢您的建议。我已经编辑了我的答案
    • 太好了,这正是我想要的。现在开始申请对我来说有点太高级了,因为我还没有完全了解LINQ。所以我猜:在一个月左右的时间内,我将开始应用您的解决方案。似乎 100% 合法
    【解决方案2】:

    试试这个... 这将为您提供列表中存在的所有重复电子邮件的列表。

     players.GroupBy(x => x.Email).SelectMany(g => g.Skip(1));
    

    【讨论】:

    • ToList() 似乎没有必要
    • 是的,实际上我在我的机器上尝试过,然后复制和粘贴添加了它。谢谢提醒
    • 嗨,我尝试了(编辑过的)版本,但由于我对 LINQ 的了解很差 atm,我无法在此基础上进一步构建。但是感谢您的建议,我可以看到您的目标。
    • 好的,我(终于)赶上了 LINQ,并想出了如何实施您的解决方案......很好的答案@KovidPurohit! var listDoubleEmail = players.GroupBy(x =&gt; x.Email).SelectMany(g =&gt; g.Skip(1)); foreach (var double in listDoubleEmail ) { Console.WriteLine(double .Email); }
    • 是的,这就是你实现的方式。
    【解决方案3】:

    Select(...)会帮你获取列表中元素的属性。

    Distinct() 将帮助您使列表包含列表中的唯一元素。

    如果要检查所有元素是否唯一,可以使用:

    bool isUnique = players.Select(x => x.Email).Distinct().Count() == players.Select(x => x.Email).Count();
    

    与:

    • players.Distinct().Count():计算唯一元素。
    • players.Count():计算列表元素。
    • 如果它们相同 (isUnique = true),则列表中的所有元素都是唯一的。

    【讨论】:

    • 我最终整合了您的建议。 1 行,非常简单易懂且 100% 有效
    【解决方案4】:

    如果您将电子邮件地址视为数据库表的键,因为它是唯一的,并且只想存储每个键/电子邮件中的一个,那么 List 可能不是最好的集合。

    您可以改用HashSet,它只接受独特的物品。

    请参阅 Microsoft 文档:https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.hashset-1?redirectedfrom=MSDN&view=net-5.0

    你这样声明

    HashSet<Player> players = new HashSet<Player>();
    

    当您尝试添加它时,它会根据它是否被接受(唯一)返回 true 到 false。

    添加到集合:

    if(players.Add(player))
        Console.Writeline($"Player {player} was added OK");
    else
        Console.Writeline($"Player with email {player.Email} already exists in the collection!");
    

    为了检查唯一性,您需要在 IEquatable&lt;T&gt; 您的班级中实现

    public class Player:  IEquatable<Player>
    {
        public string Email { get; set; }
        //Other properties, Constructor & methods etc.
       
        //It is important to implement GetHashCode!
        public override int GetHashCode()
        {
            return Email.GetHashCode();   
        }
     
        public bool Equals(Player other)
        {
            return this.Email.Equals(other.Email);
        }
    }
    

    【讨论】:

    • 未来应用的非常方便的信息。谢谢杰森!
    【解决方案5】:

    作为基本方法,您可以执行以下操作:

    List<string> controlList = new List<string>();
    foreach (var player in PlayersInfo)
    {
        if (controlList.Contains(player.Email))
        {
            Console.WriteLine("there is a duplicate with" + player.email);
        }
        else
        {
            Console.WriteLine(player.Email)
        }
        controlList.Add(player.Email);
    }
    

    【讨论】:

    • 使用HashSet&lt;string&gt; 而不是List&lt;string&gt; 会使这段代码更短、更快。
    • @TdW Rica Ederim,不客气
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-17
    • 2012-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-29
    相关资源
    最近更新 更多