nemo_87 nemo_87 - 1 month ago 11
C# Question

Check if string exists in list of strings in C#

Hello I am trying to find best and most efficient way to preform if string exists in list of strings.

My scenario is like this:


  1. Get all string values from database that are satisfying given conditions.

  2. Create random code that has 6 digits, but it is a string value.

  3. Check if generated code exists in list of strings. If it does preform generating of code again, and do it until you find unique string that does not exists in list of strings. When you find one, return it.



This is my code:

private static readonly string chars = "0123456789";

string IGenerateOtpCodeService.GenerateOtpCode()
{
var otps = personalTestSessionRepository
.FindAll(x => x.State == PersonalTestSessionStates.NotStarted)
.Select(x => x.Person.Otp)
.ToList()
.Distinct();

Random random = new Random();

string otp = new string(Enumerable.Repeat(chars, 6)
.Select(s => s[random.Next(s.Length)]).ToArray());

//preform check if otp exitst in otps list. if it does, generate otp again, else return otp
return otp;
}


What is best way to do this? Is it while loop, some LINQ expresion, or something else?

Answer

You should use Distinct before ToList to perform Distinct operation on database server. Then you can check existence of string using Any.

var otps = personalTestSessionRepository
    .FindAll(x => x.State == PersonalTestSessionStates.NotStarted)
    .Select(x => x.Person.Otp)
    .Distinct();
    .ToList();

string otp = null;
var found = true; 
do
{
    otp = new string(Enumerable.Repeat(chars, 6)
    .Select(s => s[random.Next(s.Length)]).ToArray());

    found = otps.Any(x=>x == otp);

} while(found)

return otp;

Based on heinzbeinz suggestion, the code will perform faster if you use HashSet. To use HashSet, use code below

var otpsList = personalTestSessionRepository
    .FindAll(x => x.State == PersonalTestSessionStates.NotStarted)
    .Select(x => x.Person.Otp)
    .Distinct();
    .ToList();

var otps = new HashSet<string>(otpsList);

string otp = null;
var found = true; 
do
{
    otp = new string(Enumerable.Repeat(chars, 6)
    .Select(s => s[random.Next(s.Length)]).ToArray());

    found = otps.Contains(otp);

} while(found)

return otp;
Comments