Home > Blockchain >  Comparing lists of ints in, while considering two ints not to be equal if repeated
Comparing lists of ints in, while considering two ints not to be equal if repeated

Time:09-15

I know this question has been reiterated multiple times, and I think this is straightforward when using lists of reference types. That is also what most questions talk about. When doing this with value types, I can't quite figure it out.

What I want do to is take an incoming request, and ensure that the request has at least the same numbers that are already present. Additional numbers are allowed, and the additional numbers in the request will be persisted. So if [1,2] is already persisted and the request contains [1,2,3], 3 will be persisted. If the request contained only 1 or 2, that would be invalid, and [1,2] would be valid and only the data that already existed would be returned.

The last case mentioned above I've implemented the following way:

Enumerable.SequenceEqual(existing.OrderBy(e => e), request.OrderBy(e => e));

When the lists aren't equal though, I want to treat each int in a list as if it was unique, but I can't figure out how to do this. In the following example, I would like the resulting list to be [1, 4], but it ends up being [4] due to both the numbers 1 in the existing list are excluded due to being equal.

var existing = new List<int> { 1, 1, 2, 3, 4 };
var request = new List<int> { 1, 2, 3 };
existing.Except(request).ToList();
// 4

I have seen that Except accepts a IEqualityComparer, but I stumble when trying to implement this for a value type and I don't know if this is the correct way to go.

Any help on how I should think when approaching this problem would be greatly appreciated. Efficiency is not that important, as the lists will not contain many elements at all.

CodePudding user response:

You could use regular List<T>.Remove(T):

foreach(var e in existing)
{
    var actuallyExisted = request.Remove(e);
}

actuallyExisted will be false if it couldn't find e to remove. request will now contain all ints that weren't in existing.

CodePudding user response:

Maybe there are more efficient aproaches but this gives you the desired functionality:

var result = existing
  .GroupBy(i => i)
  .SelectMany(g => Enumerable.Repeat(g.Key, Math.Max(0, g.Count() - request.Count(i => i == g.Key))));

Explanation:

The query takes every unique item in sequence1 and then repeats it 0-n times in the result. 0 if the number of occurences in sequence 2 is greater or equal than in sequence 1.

  • Related