लाइनक अभिव्यक्ति के साथ नेस्टेड वस्तुओं को कैसे समतल करना है


125

मैं इस तरह से नेस्टेड वस्तुओं को समतल करने की कोशिश कर रहा हूं:

public class Book
{
    public string Name { get; set; }
    public IList<Chapter> Chapters { get; set; }
}

public class Chapter
{
    public string Name { get; set; }
    public IList<Page> Pages { get; set; }
}


public class Page
{
    public string Name { get; set; }
}

एक उदाहरण देता हूं। यह मेरे पास डेटा है

Book: Pro Linq 
{ 
   Chapter 1: Hello Linq 
   {
      Page 1, 
      Page 2, 
      Page 3
   },
   Chapter 2: C# Language enhancements
   {
      Page 4
   },
}

परिणाम मैं देख रहा हूँ निम्नलिखित फ्लैट सूची है:

"Pro Linq", "Hello Linq", "Page 1"
"Pro Linq", "Hello Linq", "Page 2"
"Pro Linq", "Hello Linq", "Page 3"
"Pro Linq", "C# Language enhancements", "Page 4"

मैं इसे कैसे पूरा कर सकता हूं? मैं इसे चुनिंदा नए के साथ कर सकता था लेकिन मुझे बताया गया है कि एक SelectMany पर्याप्त होगा।

जवाबों:


199
myBooks.SelectMany(b => b.Chapters
    .SelectMany(c => c.Pages
        .Select(p => b.Name + ", " + c.Name + ", " + p.Name)));

बहुत बढ़िया!!! क्या होगा यदि मेरे पास परिणाम एक नई वस्तु होगी, जैसे फ्लैटबुक {बुकनाम, चैप्टरनाम, पेजनाम}?
abx78

2
@ abx78: बस अंतिम चयन को बदल दें:.Select(p => new FlatBook(b.Name, c.Name, p.Name))
user7116

धन्यवाद दोस्तों, मुझे यही चाहिए था!
abx78

1
क्या यह वही परिणाम देता है? myBooks.SelectMany(b => b.Chapters).SelectMany(c => c.Pages).Select(p => b.Name + ", " + c.Name + ", " + p.Name);
होमर

1
@ मैस्त्रो कैसे के बारे मेंmyBooks.SelectMany(b => b.Chapters == null || !b.Chapters.Any()? new []{b.Name + " has no Chapters"} : b.SelectMany(c => c.Pages.Select(p => b.Name + ", " + c.Name + ", " + p.Name)));
यूरी Faktorovich

50

मान booksलेना पुस्तक की एक सूची है:

var r = from b in books
    from c in b.Chapters
    from p in c.Pages
    select new {BookName = b.Name, ChapterName = c.Name, PageName = p.Name};

2
+1, भले ही कोई भी IEnumerable<Book>करेगा, को इसकी आवश्यकता नहीं है List<Book>
user7116

2
myBooks.SelectMany(b => b.Chapters
    .SelectMany(c => c.Pages
        .Select(p => new 
                {
                    BookName = b.Name ,
                    ChapterName = c.Name , 
                    PageName = p.Name
                });

7
हालांकि यह कोड नमूना प्रश्न का उत्तर दे सकता है, लेकिन इसमें स्पष्टीकरण का अभाव है। जैसा कि यह अब खड़ा है, यह कोई मूल्य नहीं जोड़ता है, और नीचे / हटाए जाने के परिवर्तन को खड़ा करता है। कृपया कुछ स्पष्टीकरण जोड़ें कि यह क्या है और क्यों यह ओपी की समस्या का समाधान है।
o

0

मैं यह भी करने की कोशिश कर रहा था, और यूरी की टिप्पणियों और linqPad के साथ खिलवाड़ से मेरे पास यह है ..

ध्यान दें कि मेरे पास किताबें, अध्याय, पृष्ठ नहीं हैं, मेरे पास व्यक्ति (किताबें), कंपनीपर्सन (अध्याय) और कंपनियां (पृष्ठ) हैं

from person in Person
                           join companyPerson in CompanyPerson on person.Id equals companyPerson.PersonId into companyPersonGroups
                           from companyPerson in companyPersonGroups.DefaultIfEmpty()
                           select new
                           {
                               ContactPerson = person,
                               ContactCompany = companyPerson.Company
                           };

या

Person
   .GroupJoin (
      CompanyPerson, 
      person => person.Id, 
      companyPerson => companyPerson.PersonId, 
      (person, companyPersonGroups) => 
         new  
         {
            person = person, 
            companyPersonGroups = companyPersonGroups
         }
   )
   .SelectMany (
      temp0 => temp0.companyPersonGroups.DefaultIfEmpty (), 
      (temp0, companyPerson) => 
         new  
         {
            ContactPerson = temp0.person, 
            ContactCompany = companyPerson.Company
         }
   )

रेफरी साइट जिसका मैंने उपयोग किया है: http://odetocode.com/blogs/scott/archive/2008/03/25/inner-outer-lets-all-join-tought-with-linq.aspx

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.