我如何在C#中的两个列表中获得差异?

时间:2012-03-23 14:03:16

标签: c# linq list linq-to-objects

好的,所以我在C#中有两个列表

List<Attribute> attributes = new List<Attribute>();
List<string> songs = new List<string>();

一个是字符串,一个是我创建的属性对象。非常简单

class Attribute
{
    public string size { get; set; }
    public string link { get; set; }
    public string name { get; set; }
    public Attribute(){}
    public Attribute(string s, string l, string n) 
    {
        size = s;
        link = l;
        name = n;
    }
}

我现在必须比较以查看属性名称中没有的歌曲,例如

songs.Add("something"); 
songs.Add("another"); 
songs.Add("yet another");

Attribute a = new Attribute("500", "http://google.com", "something" ); 
attributes.Add(a);

我想要一种方法来返回“另一个”和“又一个”,因为它们不在属性列表名称中

所以对于伪代码

difference = songs - attributes.names

4 个答案:

答案 0 :(得分:34)

var difference = songs.Except(attributes.Select(s=>s.name)).ToList();

修改

添加了ToList()以使其成为列表

答案 1 :(得分:6)

值得指出的是,此处发布的答案将返回songs中不存在的attributes.names列表,但它不会为您提供attributes.names中不存在的songs列表{1}}。

虽然这是OP想要的,但标题可能有点误导,特别是如果(像我一样)你来到这里寻找一种方法来检查两个列表的内容是否有所不同。如果这是您想要的,您可以使用以下内容: -

var differences = new HashSet(songs);
differences.SymmetricExceptWith(attributes.Select(a => a.name));
if (differences.Any())
{
    // The lists differ.
}

答案 2 :(得分:4)

var diff = songs.Except(attributes.Select(a => a.name)).ToList();

答案 3 :(得分:4)

这是查找属性名称中未包含的所有歌曲的方法:

var result = songs
  .Where(!attributes.Select(a => a.name).ToList().Contains(song));

使用Except的答案也很完美,可能效率更高。

编辑:如果你在LINQ to SQL中使用它,这个sintax有一个优势:它转换为NOT IN SQL谓词。 Except未转换为SQL中的任何内容。因此,在该上下文中,所有记录都将从数据库中恢复,并在应用程序端除外,效率低得多。