2015-08-25 2 views
1

Я пытался следовать, а затем распространять старый пример, Linq query list contains a list, но это не сработало для меня.Запрос LINQ, чтобы узнать, содержатся ли все элементы в списке 2 в списке 1

class Part 
{ 
    public int id { get; set; } 
    public string name { get; set; } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     { 
      List<int> L1 = new List<int> { 1, 2, 3, 4, 5, 6 }; 
      List<int> L2 = new List<int> { 4, 3 }; 

      bool t = L2.Where(p => L2.All(q => L1.Contains(q))).Any(); 
     } 



     { 
      List<Part> L1 = new List<Part> { new Part { id = 1 }, new Part { id = 2 }, new Part { id = 3 }, new Part { id = 4 } }; 
      List<Part> L2 = new List<Part> { new Part { id = 3 }, new Part { id = 4 } }; 

      bool u = L2.Where(p => L2.All(q => L1.Contains(q.id))).Any(); 
     } 
    } 
} 

Первый тест работает для меня, но не соответствует предыдущему коду, который я нашел. Мой второй тест имеет синтаксическую ошибку в «L1.Contains (q.id)». Я в тупике.

ответ

0

L1 является List<Part>, q является Part, q.id является внутр.

L1 не Contain элемент типа int

Чтобы проверить, если L1 содержит элемент с таким идентификатором, используйте Any

L2.All(q => L1.Any(e => e.id == q.id)) 
+0

Мой первый вопрос о StackOverflow и ответ <10 минут. Это фантастика. Я использовал «bool u = L2.Where (p => L2.All (q => L1.Any (e => e.id == q.id))). Any()", и я думаю, что он делает то, что я необходимость. – DustyB

+0

bool u = L2.All (q => L1.Any (e => e.id == q.id)); лучше. Мой «где» не нужен. – DustyB

0

При использовании оператора равенства вы проверяете, чтобы увидеть, если в списках содержат ссылки на одни и те же объекты. Если вы хотите совместить, вы должны сделать что-то подобное, выбрав, какие значения сравнивать. Ваша синтаксическая ошибка исходит из того факта, что вы сравниваете идентификаторы с частями. Если вы проецируете L1 на идентификаторы (L1.Select(p => p.Id)), вы должны быть хорошими.

0

На вопрос «IsContained»:

using System; 
using System.Collections.Generic; 
using System.Linq; 

public class Program 
{ 
    class Part 
    { 
     public int id { get; set; } 
     public string name { get; set; } 
    } 

    public static void Main() 
    { 
     { 
      var L1 = new List<int> { 1, 2, 3, 4, 5, 6 }; 
      var L2 = new List<int> { 4, 3 }; 

      bool t = L2.All(l2 => L1.Contains(l2)); 

      Console.WriteLine("L1 contains L2: {0}", t); 
     } 

     { 
      var L1 = new List<Part> { new Part { id = 1 }, new Part { id = 2 }, new Part { id = 3 }, new Part { id = 4 } }; 
      var L2 = new List<Part> { new Part { id = 3 }, new Part { id = 4 } }; 

      bool u = L2.All(l2 => L1.Any(l1 => l1.id == l2.id)); 

      Console.WriteLine("L1 contains L2: {0}", u); 
     } 
    } 
} 
0

Вы не можете использовать Contains там, потому что тип является List<Part>, по крайней мере, без какого-либо выступа или другого аргумента. Если вы собираетесь часто пересекать списки с этими типами, я рекомендую реализовать IEquatable<T> для такой же части;

class Part : IEquatable<Part> 
{ 
    public int id { get; set; } 
    public string name { get; set; } 

    public bool Equals(Part other) 
    { 

     //Check whether the compared object is null. 
     if (Object.ReferenceEquals(other, null)) return false; 

     //Check whether the compared object references the same data. 
     if (Object.ReferenceEquals(this, other)) return true; 

     //Check whether the products' properties are equal. 
     return id.Equals(other.id) && name.Equals(other.name); 
    } 

    // If Equals() returns true for a pair of objects 
    // then GetHashCode() must return the same value for these objects. 

    public override int GetHashCode() 
    { 

     //Get hash code for the Name field if it is not null. 
     int nameHash = name == null ? 0 : name.GetHashCode(); 

     int idHash = id.GetHashCode(); 

     //Calculate the hash code for the part. 
     return nameHash^idHash; 
    } 
} 

При этом вы можете просто сделать L1.Intersect(L2) и получить ожидаемые результаты. Если вы только собираетесь сделать это, возможно, проще написать что-то вроде; L2.All(q => L1.Any(e => e.id == q.id)), хотя я бы не рекомендовал повторное использование этого вместо Intersect.

+0

Я начал с Intersect(), но сотрудник предложил, что может быть лучший способ, который заставил меня смотреть. – DustyB

+0

@ DustyB лучше зависит от ваших потребностей. Я ожидаю, что вы используете, чтобы иметь значительно худшую производительность, как я заметил в ответе, хорошо, если вы делаете операцию один раз, если вы часто используете ее, это плохой ярлык. – evanmcdonnal

Смежные вопросы