How to get the "remainder" of a request (all inconsistent pairs) in LINQ and collect it in a list

I map requests to responses based on requestId as follows:

    public void MatchCallPairsByRequestId()
    {
        // Finds request that have matching response based on RequestId and create callpair
       _callPairs = _requests.Where(req => !string.IsNullOrEmpty(req.RequestId))
                  .Join(_responses, 
                        req => req.RequestId,
                        resp => resp.RequestId,
                        (req, resp) => new CallPair(req, resp)).ToList();
    }

or in the LINQ expression:

 _callPairs = (from req in _requests
                  join resp in _responses
                      on req.RequestId equals resp.RequestId
                      where !string.IsNullOrEmpty(req.RequestId)
                  select new CallPair(req, resp)).ToList();

Now I want to collect requests and answers that do not correspond to the function in a separate list called nonMatchedRequestsand nonMatchedResponses. How to use this query to collect the balance in a separate list?

+4
source share
3 answers

I'm not sure if there is a way to do this in one call, or perhaps even combine it with creating a list of pairs, but you can run a few of the following methods to identify unsurpassed elements:

var unmatchedRequests = _requests.Except(_callPairs.Select(cp => cp.Request));

var unmatchedResponses = _responses.Except(_callPairs.Select(cp => cp.Response));

Enumerable.Join GroupJoin , , , , .

, linq, .

+3

, .Except(), ,

// Matching pairs
_callPairs = _requests.Where(req => !string.IsNullOrEmpty(req.RequestId))
    .Join(
        _responses, 
        req => req.RequestId,
        resp => resp.RequestId, 
        (req, resp) => new CallPair(req, resp)
    ).ToList();

// To use the .Distinct() part, you're going to need to implement IEqualityComparer twice
// Easy but maybe not strictly necessary, no matter what it would be a solid approach
var matchedRequests = _callPairs.Select(cp => cp.Request); //.Distinct(new RequestComparer());
var matchedResponses = _callPairs.Select(cp => cp.Response); //.Distinct(new ResponseComparer());

var nonMatchingRequests = _requests.Except(matchedRequests);
var nonMatchingResponses = _responses.Except(matchedResponses);
+2

, CallPair

var unmatchedRequests = _requests.Where(req => !_callPairs.Any(cp => cp.Request == req));
var unmatchedResponses = _responses.Where(resp => !_callPairs.Any(cp => cp.Response == resp));

EDIT:

var requests = Enumerable.Range(0, 10).Select(i => "Request" + i).ToList();
var responses = Enumerable.Range(0, 10).Select(i => "Response" + i).ToList();

var pairs = Enumerable.Range(0, 3).Select(i => new KeyValuePair<string, string>("Request" + i, "Response" + i * 2)).ToList();

var unmatchedRequests = requests.Where(req => !pairs.Any(cp => cp.Key == req));
var unmatchedResponses = responses.Where(resp => !pairs.Any(cp => cp.Value == resp));

7 7 , . ?

+1
source

Source: https://habr.com/ru/post/1531532/


All Articles