Home > Net >  C# how to compare two List<string> and get value of duplicated element
C# how to compare two List<string> and get value of duplicated element

Time:12-13

I've got two List<string>, one contains user's IDs and their emails, second contains only emails. I am trying to find duplicated emails from second list in the first list, and input email's IDs in a variable.

Example: 1st List content:

emailswithIDs = List<string> {1, [email protected], 2, [email protected], 3, [email protected]

2nd List content:

emails = List<string> {[email protected]}

So I'd like to make variable "IDs" which would contain "2" as it is the ID of duplicated email.

I have tried:

var IDs = emails.Intersect(emailswithIDs);

But obviously it will only get the duplicated string, and I need to get the email's ID value.

CodePudding user response:

You can get the duplicates with:

List<string> duplicates = emailswithIDs.Intersect(emails).ToList();

But there is no ID's field in a List<string>. You can get the index. But there is no relation between the index and the element. Can change if you change the order.

You should do your own class:

public class myClass {
  public int ID {get;set;}
   public string email {get;set;}
}

and a list of them: List<myClass>

CodePudding user response:

You can try this one:

List<string> emailsWithIDs = new List<string> { "1", "[email protected]", "2", "[email protected]", "3", "[email protected]", "4", "[email protected]"};
List<string> emails = new List<string> { "[email protected]" };
List<string> IDs = new List<string>();

for(int i=0; i<emailsWithIDs.Count(); i =2)
{
    for(int j=0; j<emails.Count(); j  )
    {
        if(emailsWithIDs[i 1] == emails[j])
        {
            IDs.Add(emailsWithIDs[i]);
        }
    }
}

Console.WriteLine(IDs.Count());

Console.ReadKey();

CodePudding user response:

Mixing ids and values in the same List<string> is not a good practice. Let's build a dictionary (i.e. mail - id correspondence): mail will be a Key and id will be a Value:

  Dictionary<string, string> emailToId = new Dictionary<string, string>(
    StringComparer.OrdinalIgnoreCase);

  for (int i = 0; i < emailswithIDs.Count; i  = 2) 
    emailToId.Add(emailswithIDs[i   1], emailswithIDs[i]);

Then you can easily query if item in emails exists in emailToId:

  var ids = emails
    .Where(email => emailToId.ContainsKey(email))
    .Select(email => emailToId[email]);  

Please, fiddle

CodePudding user response:

If finding an email address at index n and you can guarantee that element at n-1 is the corresponding id, you can do something like this:

// For each entry in emails find the index of the same string
// In the emailswithIDs list, then take n-1 because that
// represents the index of the id in emailswithIDs
var duplicateEmailIndices = emails
    .Select(x => emailswithIDs.IndexOf(x))
    .Where(x => x >= 1)
    .Select(x => x - 1);

// Get the entries from emailswithIDs at each index given
// in duplicateEmailIndices
var duplicateIds = emailswithIDs.Where((id, index) => duplicateEmailIndices.Contains(index));

This, of course, only provides a solution for the code as it is written currently. There are better solutions, such as Dictionary, as pointed out in another answer. It also assumes that the emailswithIDs list will always contain data in the order of id, email, id, email...

  •  Tags:  
  • c#
  • Related