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...