I am matching requests with 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 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 the requests and responses that are not matched by the function in a separate list called nonMatchedRequests
and nonMatchedResponses
. How do I use this query to collect the remainder in a separate list?
I'm not sure if there is a way to do this in one call or perhaps even merge it with producing the list of pairs, but you can run a couple of follow up methods to determine the unmatched items:
var unmatchedRequests = _requests.Except(_callPairs.Select(cp => cp.Request));
var unmatchedResponses = _responses.Except(_callPairs.Select(cp => cp.Response));
The documentation for Enumerable.Join
also talks of being able to use GroupJoin
to perform an outer join, as detailed here, this will return unmatched requests, though I think it would miss unmatched responses.
I await with bated breath the answer demonstrating linq wizardry that does this more efficiently with one call.
You probably can do this through .Except()
, maybe also operating on distinct values
// 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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With