获取两个大型列表之间的所有不匹配元素

时间:2016-01-27 16:25:27

标签: c# dictionary

我有dictionary<string, Foo>个X元素。字典键包含Foo.Id。我还有一个List<Foo> newFoos,在我的情况下包含的元素比字典少一些。所以我想做的是,有一个新的List<Foo>包含newFoos中的所有元素,但不在我的字典中。

我通过使用:

解决了这个问题
var list = MyDict.Where(x => newFoos.All(y => y.Id != x.Key)).ToList();

但问题是在我的情况下,它必须是一些更容易和更快的方式吗?请不要使用Except / Intersect并覆盖Equals

    public class Program {

    public static Dictionary<int, Foo> MyDict { get; set; } = new Dictionary<int, Foo>(); 
    private static void Main(string[] args) {
        for (int i = 0; i < 2000; i++) {
            MyDict.Add(i, new Foo() {Id = i});
        }

        var newFoos = new List<Foo>();
        for (int i = 0; i < 1500; i++) {
            newFoos.Add(new Foo() { Id = i });
        }

        var list = MyDict.Where(x => newFoos.All(y => y.Id != x.Key)).ToList();
    }
}

public class Foo  {

    public int Id { get; set; }

    //More properties

}

当我使用上面的测试代码时,我发现它并不那么慢,但原理是相同的

2 个答案:

答案 0 :(得分:3)

var list = newFoos.Where(x => !MyDict.ContainsKey(x.Id)).ToList();

这应该更有效率,因为检查密钥是否在字典中应该比查找列表中的项目更快。

答案 1 :(得分:0)

我假设列表上的索引访问速度比使用枚举器略快。如前所述,检查密钥存在也比访问每个项目快得多,这导致了... ContainsKey ...

double

如果您打算将它们添加到字典中,取决于newFoos的数量,最好在找到它们之后添加项目而不是在循环中,因为否则您将在搜索时将放大字典反正永远不会打击。