No duplicate items in a list

Nick R 66 Reputation points
2023-03-05T22:03:46.9266667+00:00

Good day everyone!

Hoping to get some help on a problem.

I have an application where users can enter events and then are assigned a random card, 1-14, but each user must have a card that isn't a duplicate of another user's card.

So when Joe enters an Event, Jill won't get the same card as Joe, and Jose won't get the same card as Joe or Jill and so on.

I have written some code, as shown below, but seems duplicate cards pop up.

Any help would be greatly appreciated, thank you!

var random = new Random();
var cards = await _cardService.GetAllCardsAsync();
var index = random.Next(cards.Count);

await _eventService.InsertEntryAsync(new Entry
{
   UserId = currentUser.Id, //id of current logged in user
   CardId = cards[index].Id
});
ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,118 questions
ASP.NET
ASP.NET
A set of technologies in the .NET Framework for building web applications and XML web services.
3,234 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,164 questions
{count} votes

3 answers

Sort by: Most helpful
  1. Karen Payne MVP 35,026 Reputation points
    2023-03-05T23:59:04.18+00:00

    Consider a Dictionary using identifiers from your data, below is a static mockup

    private static readonly Dictionary<int, bool> _dictionary = 
        Enumerable.Range(1, 15).Select(index =>
            new { Key = index, Value = false })
            .ToDictionary(x => x.Key, x => x.Value);
    

    Create a list of keys/identifiers

    private List<int> _keyList = new(_dictionary.Keys);
    

    Then in a method...

    if (_keyList.Count >0)
    {
        Random rand = new Random();
        var index = _keyList[rand.Next(_keyList.Count)];
        // use index and remove from list
        _keyList.Remove(index);
    }
    else
    {
        // all used up
    }
    

  2. Nick R 66 Reputation points
    2023-03-06T15:51:11.4166667+00:00

    I've been messing around with my code some and decided to do a do while loop.

    I might be using the do while loop wrong.

    public async Task<IActionResult> SaveEntry(int item)
    {
       var @event = await _eventService.GetEventByIdAsync(item);
       //other code
    
       var cards = await _cardService.GetAllCardsAsync();
       var random = new Random();
       var index = random.Next(cards.Count);
       var entries = await _eventService.GetAllEntriesAsync(@event.Id);
    
       bool isFound = false;
       do
       {
          foreach (var entry in entries)
          {
             if (entry.CardId == cards[index].Id)
             {
                isFound = true;
                break;
             }
          }
    
          if (isFound is false)
          {
             await _eventService.InsertEntryAsync(new Entry
             {
                EventId = @event.Id,
                UserId = currentUser.Id,
                CardId = cards[index].Id
             });
          }
       } while (isFound);
    
       return Json(new
       {
          status = true,
          msg = "You have successfully entered this event."
       });
    }
    
    

    My small issue here is that when User B clicks on "Enter Event" button in "View.cshtml" and the card is already used by another user, User B has to keep clicking on Enter Event until a card that isn't used is then assigned to User B.


  3. Ruikai Feng - MSFT 2,526 Reputation points Microsoft Vendor
    2023-03-07T02:47:57.31+00:00

    Hi,@Nick R

    I tried with a minimal example as below:

    CardService:

    public interface ICardService
        {
            void Initialize(List<int> innitialcards);      
            int GetCardId(int UserId);
        }
        public class CardService : ICardService
        {
            private  List<int> Cards { get; set; }=new List<int>(){};
            private Dictionary<int, int> User_Cards { get; set; }=new Dictionary<int, int>(){};      
            public int GetCardId(int UserId)
            {
               
                if (User_Cards.ContainsKey(UserId))
                {
                    return User_Cards[UserId];
                }
                if (Cards.Count==0)
                {
                    return 0;
                }
                var itemunm=Random.Shared.Next(0, Cards.Count);
                var result=Cards[itemunm];
                User_Cards.Add(UserId,Cards[itemunm]);
                Cards.Remove(Cards[itemunm]);
                return result;
            }
            public void Initialize(List<int> innitialcards)
            {
                Cards = innitialcards;
                User_Cards.Clear();
            }
        }
    

    Regist the service:(it's important to regist the service with Singleton,you could check the document related with servicelifetime)

    builder.Services.AddSingleton<ICardService, CardService>();
    

    Controller:

    public class CardsController : ControllerBase
        {
           
            private readonly ICardService _cardService;
            public CardsController(ICardService cardService)
            {
                _cardService = cardService;
            }
            [HttpGet]
            public string Get(int UserId)
            {
                var cardId=_cardService.GetCardId(UserId);
                if (cardId == 0)
                {
                    return "no cards now";
                }
                return cardId.ToString();
            }
            [HttpPost]
            public void InnitializeCards([FromBody] List<int> Cards)
            {
                _cardService.Initialize(Cards);
            }
        }
    

    Result:

    3.7


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,

    Ruikai Feng

    0 comments No comments