说我有两个列表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做到这一点?
答案 0 :(得分:3)
您可以使用Where
+ Any
和HttpUtility.ParseQueryString
来检查查询字符串是否与Scheme
相关联:
var newNotInOld = newTiles
.Where(nt => !oldTiles
.Any(ot => ot.Scheme.Equals(HttpUtility.ParseQueryString(nt.Navigation.ToString())["Scheme"], StringComparison.InvariantCultureIgnoreCase)));
您需要添加using System.Linq
和using 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;
}