linq जहाँ लिस्ट में कोई भी लिस्ट होती है


117

Linq का उपयोग करके, मैं उन वस्तुओं की एक सूची कैसे प्राप्त कर सकता हूं, जहां इसकी विशेषताओं की सूची किसी अन्य सूची से मेल खाती है?

इस सरल उदाहरण और छद्म कोड को लें:

List<Genres> listofGenres = new List<Genre>() { "action", "comedy" });   
var movies = _db.Movies.Where(p => p.Genres.Any() in listofGenres);

जवाबों:


202

आप चाहते हैं जैसे लगता है:

var movies = _db.Movies.Where(p => p.Genres.Intersect(listOfGenres).Any());

मैं खोज बॉक्स के लिए इस क्वेरी का उपयोग करने की कोशिश कर रहा था, यह Personal_Name कॉलम में किसी भी वर्ण को खोजता है, मुझे यह त्रुटि मिली: 'DbIntersectExpression को संगत संग्रह के साथ तर्क की आवश्यकता है' इसलिए मैंने यहाँ.StartWith, .EndsWith, .Contains से कोशिश की कि यह काम करे, लेकिन आपकी क्वेरी का उपयोग करने के लिए क्या किया जा सकता है
शैजुत

@stom: हमारे पास आपकी सहायता करने के लिए लगभग पर्याप्त जानकारी नहीं है - आपको एक नया प्रश्न बहुत अधिक संदर्भ के साथ पूछना चाहिए ।
जॉन स्कीट

@JonSkeet मैं हमेशा इस तरह के प्रश्नों के लिए कंटेंस विधि का उपयोग करता हूं। मैं आपके उत्तर को देखकर उत्सुक था और आंतरिक कार्यान्वयन की जाँच की और पाया कि Intersect Set का उपयोग करता है। क्या आप मुझे उन दो तरीकों के बीच प्रदर्शन अंतर बता सकते हैं?
पुनर्जन्म

6
@Rebornx: Containsसमय में O (x * y) ऑपरेशन के रूप में बार-बार समाप्त होता है, लेकिन O (1) अंतरिक्ष में, जहां x पहले संग्रह का आकार है और y दूसरे का आकार है। समय Intersectमें O (x + y) का उपयोग करना है लेकिन अंतरिक्ष में O (y) - यह दूसरे संग्रह से एक हैशसेट का निर्माण करता है, जो पहले संग्रह से किसी भी आइटम के लिए समावेश की जांच करने के लिए त्वरित बनाता है। देखें codeblog.jonskeet.uk/2010/12/30/... जानकारी के लिए
जॉन स्कीट

1
@SteveBoniface: मैं ऐसा करने की उम्मीद नहीं है, नहीं। मुझे उम्मीद है कि बाद में बहुत कम तेजी होगी, क्योंकि कम अप्रत्यक्ष है।
जॉन स्कीट


5

आप का उपयोग करते हैं HashSetबजाय Listके लिए listofGenresआप कर सकते हैं:

var genres = new HashSet<Genre>() { "action", "comedy" };   
var movies = _db.Movies.Where(p => genres.Overlaps(p.Genres));

3

मुझे लगता है कि यह भी इस तरह संभव है?

var movies = _db.Movies.TakeWhile(p => p.Genres.Any(x => listOfGenres.Contains(x));

क्या "टेकविले" प्रदर्शन या स्पष्टता के अर्थ में "कहाँ" से भी बदतर है?


TakeWhileएक अलग कार्य है - यह एक मैच नहीं मिलने पर पुनरावृत्ति को रोक देगा।
डी स्टैनले

1

या इस तरह

class Movie
{
  public string FilmName { get; set; }
  public string Genre { get; set; }
}

...

var listofGenres = new List<string> { "action", "comedy" };

var Movies = new List<Movie> {new Movie {Genre="action", FilmName="Film1"},
                new Movie {Genre="comedy", FilmName="Film2"},
                new Movie {Genre="comedy", FilmName="Film3"},
                new Movie {Genre="tragedy", FilmName="Film4"}};

var movies = Movies.Join(listofGenres, x => x.Genre, y => y, (x, y) => x).ToList();
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.