LINQ:根据属性比较两个列表并返回符合特定条件的项目

时间:2014-05-12 09:26:22

标签: c# linq list windows-phone-8

说我有两个列表List<NewTile>List<OldTile>List<OldTile>总是包含的项目多于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; }    
}

例如Navigation属性总是包含Scheme字符串。这两个列表之间的项目是如何相关的。

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

我想从List<NewTile>获取其导航属性与Scheme List<OldTile>中的任何一个{{1}}字符串不匹配的所有项目。我如何使用LINQ做到这一点?

2 个答案:

答案 0 :(得分:3)

您可以使用Where + AnyHttpUtility.ParseQueryString来检查查询字符串是否与Scheme相关联:

var newNotInOld = newTiles
    .Where(nt => !oldTiles
        .Any(ot => ot.Scheme.Equals(HttpUtility.ParseQueryString(nt.Navigation.ToString())["Scheme"], StringComparison.InvariantCultureIgnoreCase)));

您需要添加using System.Linqusing System.Web

由于您使用的是Windows手机,因此您没有HttpUtility.ParseQueryString。所以可以尝试这种方法:http://dotnetautor.de/blog/2012/06/25/WindowsPhoneParseQueryString.aspx

除此之外,您还可以使用字符串方法或正则表达式。例如:

 var newNotInOld = newTiles
  .Where(nt => !oldTiles
    .Any(ot => {
       string url = nt.Navigation.ToString();
       int index = url.IndexOf('?');
       bool containsScheme = false;
       if (index >= 0)
       {
           string queryString = url.Substring(++index);
           containsScheme = queryString.Split('&')
             .Any(p => p.Split('=')[0].Equals("Scheme", StringComparison.InvariantCulture) 
                    && p.Split('=').Last().Equals(ot.Scheme, StringComparison.InvariantCultureIgnoreCase));
       }
       return containsScheme;
   }));

答案 1 :(得分:2)

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

这个的计算复杂性是O(n2)我相信,所以小心处理大型列表。

修改

至于解析参数(没有HttpUtility),可以使用 Uri Regex 来完成。

诀窍在于,由于你只有一个亲戚Uri,你需要在现场创建一个绝对的。{/ p>

以下方法对我有用:

    string GetScheme(string relativeUri)
    {
        string fakeSite = "http://fake.com"; // 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;        
    }