Как получить разницу в двух списках в C#?

Итак, у меня есть два списка в 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);

Я хочу, чтобы способ вернуть "другой "и" еще один", потому что они не находятся в списке атрибутов name

Итак, для псевдокода

difference = songs - attributes.names

4 ответов


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

редактировать

добавлен ToList (), чтобы сделать его списком


стоит отметить, что ответы, размещенные здесь возвращает список songs нет в attributes.names, но он не даст вам список attributes.names нет в songs.

хотя это то, что хотел OP, название может быть немного вводящим в заблуждение, особенно если (как и я) вы пришли сюда в поисках способа проверить, отличается ли содержимое двух списков. Если это то, что вы хотите, вы можете использовать следующее:-

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

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

Это способ, чтобы найти все песни, которые не включены в имена атрибутов:

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

ответ, использующий Except, также идеален и, вероятно, более эффективен.

EDIT: этот sintax имеет одно преимущество, если вы используете его в LINQ to SQL: он переводится в NOT IN предикат SQL. Except не переводится ни на что в SQL. Таким образом, в этом контексте все записи будут восстановлены из базы данных и исключены со стороны приложения, что намного меньше эффективный.