优化双foreach循环
我有一个双foreach循环,并希望通过使它成为一个循环而不是两个来加速它。
这个想法是它从字典中获取一个元素并将其与字典中的所有元素进行比较
foreach (KeyValuePair kvp in originCounts) { foreach (KeyValuePair testkvp in originCounts) { //Run Comparison on testkvp ad kvp } }
我想把它变成一个循环,任何建议?
您可以使用Enumerable.All
来检查所有元素是否相同:
var firstID = originCounts.First().Value.UserID; bool allEquals = originCounts.Skip(1).All(o => o.Value.UserID == firstID);
看来这就是你真正想要的。
我刚刚在重复的问题中选出了你class级的一个字段,听起来是一个合理的标识符。
public class MyObject { public string FirstName{ get; set; } public string LastName{ get; set; } public int UserID { get; set; } public string Address { get; set; } }
编辑 :根据您的评论,您要确定任何对象的字段是否与另一个对象的同一字段不同。
var first = originCounts.First().Value; bool allEquals = originCounts.Skip(1).All(o => o.Value.FirstName == first.FirstName && o.Value.LastName == first.LastName && o.Value.UserID == first.UserID && o.Value.Address == first.Address);
您可以尝试使用linq语法并比较性能
例如
foreach(KeyValuePair kvp1 in originCounts.SelectMany(kvp1 => originCounts.Select(testkvp => kvp1), (kvp1, kvp) => kvp1)) { }
要么
foreach(KeyValuePair kvp1 in from kvp1 in originCounts from kvp in originCounts.Select(testkvp => kvp1) select kvp1) { }
您可以创建一个可比较的字符串键值类来实现IComparable接口。
public class ComparableString : IComparable { public Int64 Key { get; set; } public string Value { get; set; } public int CompareTo(object obj) { if (obj == null) return 1; string otherString = obj as ComparableString; if (otherString != null) { // PLACE YOUR COMPARE LOGIC HERE return this.Value.CompareTo(otherString.Value); } else { throw new ArgumentException("Object is not a Comparable String"); } } }
完成后,您可以创建链接列表并运行.sort方法
var originCounts= new List(); // Logic to fill your list originCounts.Sort();
.Sort方法的平均复杂度为O(n(log n)),最坏的情况为O(n ^ 2),请参阅http://msdn.microsoft.com/en-us/library/b0zbh7b6.aspx了解更多信息信息。
一旦调用.Sort()方法,您就会知道项目索引之前的任何值小于或等于项目的值,并且任何大于您所在索引的索引都大于或等于你的物品的价值。
也许我通过误解这个问题来过度简化这个问题,但是如果你只是想在字符串中找到重复的值,你可以使用Dictionary的Values属性,并对它们做一个区别。
使用您的词典示例:
Dictionary originalCounts = new Dictionary(); for (Int64 i = 0; i < 10; i++) { originalCounts.Add(i, i.ToString()); } originalCounts[5] = originalCounts[3]; foreach (var kvp in originalCounts) { Console.WriteLine("{0} {1}", kvp.Key, kvp.Value); } Console.WriteLine(); foreach (var value in originalCounts.Values.Distinct()) { Console.WriteLine("{0}", value); }
如果我理解正确,要获取不同的对象(不实现IComparable或覆盖Equals和GetHashcode):
var noDups = originCounts //Any Prop. you want to compare .GroupBy(o => new { o.FirstName, o.LastName, o.UserID, o.Address }) .Select(g => g.First()) .ToList();
为什么要将字典条目与同一字典中的其他条目进行比较? 你在检查重复吗? 如果是这样,您可以使用originCounts.Distinct()
。
编辑:您需要为Distinct
方法指定IEqualityComparer
,否则它只会比较键(在Dictionary
中始终不同),而不是值。