LINQ: Compare two lists based on their properties and return items that match certain conditions


Say I have two list List<NewTile> and List<OldTile>. The List<OldTile> always contains more items than the List<NewTile>.

public class NewTile
    public Uri Navigation { get; set; }
    public string Info { get; set; }

public class OldTile
    public String Scheme { get; set; }
    public string Status { get; set; }

The Navigation property always contains the Scheme string for example.That's how items are related between those two lists.

Scheme = "wikipedia"
Navigation = "/Pages/BlankPage.xaml?Scheme=wikipedia"

I want to get all items from List<NewTile> where their Navigation property does not match any of them Scheme string from List<OldTile>. How do I do this using LINQ?

IEnumerable<NewTile> filtered = newTiles // get me all new tiles...
        newTile => // ...for which it's true that...
                .All( // ...for all the old tiles...
                    oldTile =>
                        !newTile.Navigation.OriginalString.EndsWith("?Scheme=" + oldTile.Scheme)));
                        // ...this condition is met.

Computational complexity of this is O(n2) I believe, so careful with handling large lists.


As for parsing the parameters (without HttpUtility), this can be done with an Uri and a Regex.

The trick is that since you only have a relative Uri, you need to create an absolute one on the spot.

The following method worked for me:

    string GetScheme(string relativeUri)
        string fakeSite = ""; // as the following code wouldn't work on relative Uri!
        Uri uri = new Uri(fakeSite + relativeUri);
        string query = uri.Query;
        string regexPattern = Regex.Escape("?Scheme=") + "(?<scheme>\\w+)";
        Match match = new Regex(regexPattern).Match(query);
        if (match.Captures.Count > 0)
            return match.Groups["scheme"].Value;
        return String.Empty;