There are 2 arrays, the first array of the following type:

public class ListOfUsers { public Guid idUser { get; set; } public string FIO { get; set; } } 

The second array is an IEnumerable<Guid> .

 public ICollection<ListOfUsers> First { get; set; } public IEnumerable<Guid> Second { get; set; } public ICollection<ListOfUsers> Result { get; set; } 

The First array contains the unique identifier of the user and his full name. The Second array contains only unique user IDs. How do I compare these arrays as follows:

If the element of the array First is in the array Second, then skip it. If not, then add this element to the Result array and, at the end, sort the array of results by the FIO field?

I tried to do this in the following way, but for me everything is duplicated as many times as there are elements in the Second array:

 foreach (var second in Second) { foreach (var first in First) { if (second != first.idUser) { Ressult.Add(new ListOfUsers { idUser = first.idUser, FIO = first.FIO }); } } } 
  • HashSet has an ExceptWith method ExceptWith Only the type must be the same - Grundy
  • @Grundy on this and asked the question that the types do not match and you need to somehow figure out how to do it correctly - Sanvirtus pm
  • one
    I do not know where to write, but Second is better to do the type of HashSet. Then, from the provided Any answer, you will no longer need it; use the Contains method instead. Due to the fact that HashSet stores hashcodes and searches them, then searching them in computing resources will cost less. - adrug
  • one
    Some tips on code and names: instead of idUser, you need to write UserId, this is correct from the point of view of the English language and in C # usually public properties are written with a capital letter. Next you have a class called ListOfUsers (which translates to "user list"), but your class is not the list itself, it's just a user. - B. Vandyshev
  • one
    Also, if you name variables in English, instead of FIO you should write FullName (full name). There is also FirstName (first name), LastName (surname), MiddleName (middle name, it is a middle name) - B. Vandyshev

2 answers 2

First of all, you mixed up what and how you iterate (write - you need to bypass first, and start the outer loop with second).

Secondly, the entry check was written incorrectly.

 var first = new List<ListOfUsers> { new ListOfUsers { idUser = Guid.Parse("B7AADF05-1F63-4A20-94B1-9A31F4AB4910"), FIO = "Ivan Ivanov"}, new ListOfUsers { idUser = Guid.Parse("B7AADF05-1F63-4A20-94B1-9A31F4AB4911"), FIO = "Petr Petrov"}, new ListOfUsers { idUser = Guid.Parse("B7AADF05-1F63-4A20-94B1-9A31F4AB4912"), FIO = "AK"}, new ListOfUsers { idUser = Guid.Parse("B7AADF05-1F63-4A20-94B1-9A31F4AB4913"), FIO = "Sanvirtus Sanvirtus"}, }; var second = new List<Guid> { Guid.Parse("B7AADF05-1F63-4A20-94B1-9A31F4AB4910"), Guid.Parse("B7AADF05-1F63-4A20-94B1-9A31F4AB4911"), }; var result = new List<ListOfUsers>(); foreach (var element in first) { var isElementPresentInSecond = second.Any(x => x == element.idUser); if(isElementPresentInSecond) { continue; } else { result.Add(element); } } 

enter image description here

To you on independent work:

  • replace isElementPresentInSecond from linq with language primitives
  • sort result

PS Theme is waiting for hell linq-one-liners;)

  • Thanks, it helped, I understood my mistake) - Sanvirtus
  • one
    result = first.Where(a => !second.Any(b => a.idUser == b)) - what the hell is that? - Grundy
  • one
    This algorithm is too superimposed, it works in O (n ^ 2), since you bypass all elements in the second for each element in first. Below, the IEqualityComparer version is much better and works for O (n), Microsoft specifically made it to solve this problem. - B. Vandyshev 7:55 pm

Alternatively, you can use HashSet and its ExceptWith method

Or the Except method from the LINQ set.

In both cases, you need a class that implements IEqualityComparer . It might look like this:

 class ListOfUsersByIdEqualityCmparer : IEqualityComparer<ListOfUsers> { public bool Equals(ListOfUsers x, ListOfUsers y) { return x?.IdUser == y?.IdUser; } public int GetHashCode(ListOfUsers obj) { return obj?.IdUser.GetHashCode() ?? 0; } } 

Further, the code may look like this:

  1. when using HashSet

     var result = new HashSet(first, new ListOfUsersByIdEqualityCmparer()); result.ExceptWith(second.Select(s=>new ListOfUsers(){ idUser = s })); 
  2. when using Except:

     var result = first.Except(second.Select(s => new ListOfUsers() { IdUser = s }), new ListOfUsersByIdEqualityCmparer());