मैं एक संग्रह में बाल संग्रह को एक बड़े संग्रह में एकत्रित करने के लिए एक सुरुचिपूर्ण समाधान की तलाश में हूं। मेरी समस्या तब होती है जब कुछ बाल संग्रह शून्य हो सकते हैं।

ईजी:

var aggregatedChildCollection = parentCollection.SelectMany(x=> x.ChildCollection);

यह अपवाद फेंकता है कि कोई भी बाल संग्रह ऑब्जेक्ट शून्य होना चाहिए। कुछ विकल्प हैं:

// option 1
var aggregatedChildCollection = parentCollection
    .Where(x=>x.ChildCollection != null)
    .SelectMany(x => x.ChildCollection);

// option 2
var aggregatedChildCollection = parentCollection
    .SelectMany(x => x.ChildCollection ?? new TypeOfChildCollection[0]);

दोनों काम करेंगे लेकिन मैं माता-पिता पर कुछ बाल संग्रह पर एक निश्चित ऑपरेशन कर रहा हूं, और यह थोड़ा सा बोझिल होता जा रहा है।

मैं जो चाहता हूं वह एक विस्तार विधि बनाना है जो जांचता है कि संग्रह शून्य है या नहीं और यदि ऐसा है तो विकल्प 2 क्या करता है - एक खाली सरणी जोड़ता है। लेकिन फंक की मेरी समझ उस बिंदु तक नहीं है जहां मुझे पता है कि इस विस्तार विधि को कैसे कोड किया जाए। मुझे पता है कि मुझे जो सिंटैक्स चाहिए वह इस तरह है:

var aggregatedChildCollection = parentCollection.SelectManyIgnoringNull(x => x.ChildCollection);

क्या कोई सरल विस्तार विधि है जो इसे पूरा करेगी?

5
DenverCoder9 6 सितंबर 2016, 02:55

4 जवाब

सबसे बढ़िया उत्तर

आप एक कस्टम एक्सटेंशन विधि का उपयोग कर सकते हैं:

public static IEnumerable<TResult> SelectManyIgnoringNull<TSource, TResult>(
    this IEnumerable<TSource> source, 
    Func<TSource, IEnumerable<TResult>> selector)
{
    return source.Select(selector)
        .Where(e => e != null)
        .SelectMany(e => e);
}

और इस तरह प्रयोग करें:

var aggregatedChildCollection = parentCollection
    .SelectManyIgnoringNull(x => x.ChildCollection);
3
DavidG 6 सितंबर 2016, 03:21

यदि ParentCollection आपकी अपनी कक्षा है तो आपको कक्षा के लिए एक डिफ़ॉल्ट कंस्ट्रक्टर भी सक्षम होना चाहिए जैसे:

public ParentCollection{
    public ParentCollection() {
        ChildCollection = new List<ChildCollection>();
    }
}

इससे नल रेफ अपवाद को रोका जाना चाहिए और इसमें कुछ भी नहीं होने पर आपको एक खाली सूची देनी चाहिए। कम से कम यह ईएफ मॉडल के साथ काम करता है।

1
Eonasdan 6 सितंबर 2016, 03:06

आपका "विकल्प 2" वह है जो मैं एक मामूली ट्वीक के साथ करूंगा: Enumerable.Empty() का उपयोग करें एक खाली सरणी बनाने के बजाय आपके द्वारा बनाई जा रही नई वस्तुओं की मात्रा को कम करने के लिए।

मैं एक तुच्छ विस्तार विधि का उपयोग करता हूं Touch() -- *nix उपयोगिता के नाम पर -- LINQ सिंटैक्स प्रवाह बनाए रखने और टाइपिंग कम करने के लिए:

public static IEnumerable<T> Touch<T>(this IEnumerable<T> items) =>
    items ?? Enumerable.Empty<T>();

और इसका उपयोग इस प्रकार करेंगे:

var aggregatedChildCollection = parentCollection
    .SelectMany(x => x.ChildCollection.Touch());
1
Cory Nelson 6 सितंबर 2016, 03:19

आप SelectMany संदर्भ स्रोत

public static IEnumerable<TResult> SelectManyNotNull<TSource, TResult>(
         this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector) 
{
    foreach (TSource element in source)
    {
        var subElements = selector(element);
        if (subElements != null)
            foreach (TResult subElement in subElements )
                yield return subElement;
    }
}
2
Slai 1 पद 2020, 17:08