我有一个例如List<string> ListProviderKeys
的列表,其中包含一些值。
我还有下面一个类的第二个列表,例如List<ChangesSummary> SecondList;
public class ChangesSummary
{
public string TableName { get; set; }
public string ProviderKey { get; set; }
public string ProviderAdrsKey { get; set; }
public string ProviderSpecialtyKey { get; set; }
public string FieldName{ get; set; }
}
想象一下,第一个列表保存的值与我们在第二个列表中放入ProviderKey
字段的值相同。
现在我想要的是缩小第二个列表,使其ProviderKey
不的值已经存在于第一个列表中。
我怎样才能做到这一点?我知道操作员除了但不确定如何在这种情况下应用它!
答案 0 :(得分:1)
我能想到的最好的是:
A)创建字典并使用其快速查找
B)在此字典中使用LINQ .Where
方法和.ContainsKey()
,该字典在内部使用Hashtable
并执行快速查找。
这会将搜索复杂性降低到差不多O(1)
而不是O(N)
更糟(当我们使用LINQ .Where()
与.Any()
或.Contains()
时,这会导致嵌套循环)。
来自MSDN page:
Dictionary泛型类提供从一组键到的映射 一组价值观。字典的每个添加都包含一个值 及其相关密钥。使用其键检索值非常有用 快,接近O(1),因为Dictionary类实现为 哈希表。
所以我们能做的是:
Dictionary<string, string> dict = ListProviderKeys.ToDictionary(s => s);
var newList = SecondList.Where(e => !dict.ContainsKey(e.ProviderKey)).ToList();
这是一个非常简单,简短但完整的示例,说明了它并测试了它的性能:
class Person
{
public int Id { get; set; }
}
class Program
{
static void Main(string[] args)
{
List<int> ints = new List<int>();
List<Person> People = new List<Person>(1000);
for (int i = 0; i < 7500; i++)
{
ints.Add(i);
ints.Add(15000 - i - 1);
}
for (int i = 0; i < 45000; i++)
People.Add(new Person() { Id = i });
Stopwatch s = new Stopwatch();
s.Start();
// code A (feel free to uncomment it)
//Dictionary<int, int> dict = ints.ToDictionary(p => p);
//List<Person> newList = People.Where(p => !dict.ContainsKey(p.Id)).ToList();
// code B
List<Person> newList = People.Where(p => !ints.Contains(p.Id)).ToList();
s.Stop();
Console.WriteLine(s.ElapsedMilliseconds);
Console.WriteLine("Number of elements " + newList.Count);
Console.ReadKey();
}
在发布模式下,结果为:
代码A&amp;代码B输出30 000个元素但是:
代码B花了超过2000毫秒,代码A花了5毫秒
答案 1 :(得分:0)
public class Programm
{
public static void Main()
{
List<ChangesSummary> summaries = new List<ChangesSummary>();
summaries.Add(new ChangesSummary()
{
FieldName = "1",
ProviderKey = "Test1",
});
summaries.Add(new ChangesSummary()
{
FieldName = "2",
ProviderKey = "Test2",
});
summaries.Add(new ChangesSummary()
{
FieldName = "3",
ProviderKey = "Test3",
});
List<string> listProviderKeys = new List<string>();
listProviderKeys.Add("Test1");
listProviderKeys.Add("Test3");
var res = summaries.Where(x => !listProviderKeys.Contains(x.ProviderKey));
res.ToList().ForEach(x => Console.WriteLine(x.ProviderKey));
Console.ReadLine();
}
}
public class ChangesSummary
{
public string TableName { get; set; }
public string ProviderKey { get; set; }
public string ProviderAdrsKey { get; set; }
public string ProviderSpecialtyKey { get; set; }
public string FieldName { get; set; }
}
答案 2 :(得分:-1)
我认为在这种情况下,简单Where
将更容易,更易于应用。
var first = new List<string> { "a" };
var second = new List<ChangesSummary>()
{
new ChangesSummary() { ProviderKey = "a" },
new ChangesSummary() { ProviderKey = "b" }
};
var result = second.Where(item => !first.Contains(item.ProviderKey));
// result
// .ToList()
// .ForEach(item => Console.WriteLine(item.ProviderKey));
答案 3 :(得分:-2)
我相信这会奏效:
List<ChangesSummary> ExceptionList = SecondList.
Where(x => !ListProviderKeys.Any(key => x.ProviderKey == key)).ToList();