LINQ: "समाहित है" और एक लैम्ब्डा क्वेरी


168

मेरे पास एक List<BuildingStatus>कॉल है buildingStatus। मैं यह जाँचना चाहता हूँ कि क्या यह एक स्थिति है जिसका चार कोड (द्वारा लौटाया गया GetCharCode()) कुछ चर के बराबर है v.Status

क्या नीचे (गैर-संकलन) कोड की तर्ज पर ऐसा करने का कोई तरीका है?

buildingStatus.Contains(item => item.GetCharValue() == v.Status)

जवाबों:


320

का प्रयोग करें Any()बजाय Contains():

buildingStatus.Any(item => item.GetCharValue() == v.Status)

13
अच्छा लगा। मैं सोचता रहता हूं कि पृथ्वी पर लिनक एक Contains()विधि क्यों नहीं प्रदान करता है , और तब मुझे एहसास हुआ कि Any()इसके बजाय यह होना चाहिए । +1
नोलोनर

38

Linq विस्तार विधि कोई भी आपके लिए काम कर सकता है ...

buildingStatus.Any(item => item.GetCharValue() == v.Status)

4

यहां बताया गया है कि आप Containsजो चाहते हैं उसे प्राप्त करने के लिए उपयोग कर सकते हैं:

buildingStatus.Select(item => item.GetCharValue()).Contains(v.Status) यह बूलियन मान लौटाएगा।


3

मुझे यकीन नहीं है कि आप क्या देख रहे हैं, लेकिन यह कार्यक्रम:

    public class Building
    {
        public enum StatusType
        {
            open,
            closed,
            weird,
        };

        public string Name { get; set; }
        public StatusType Status { get; set; }
    }

    public static List <Building> buildingList = new List<Building> ()
    {
        new Building () { Name = "one", Status = Building.StatusType.open },
        new Building () { Name = "two", Status = Building.StatusType.closed },
        new Building () { Name = "three", Status = Building.StatusType.weird },

        new Building () { Name = "four", Status = Building.StatusType.open },
        new Building () { Name = "five", Status = Building.StatusType.closed },
        new Building () { Name = "six", Status = Building.StatusType.weird },
    };

    static void Main (string [] args)
    {
        var statusList = new List<Building.StatusType> () { Building.StatusType.open, Building.StatusType.closed };

        var q = from building in buildingList
                where statusList.Contains (building.Status)
                select building;

        foreach ( var b in q )
            Console.WriteLine ("{0}: {1}", b.Name, b.Status);
    }

अपेक्षित उत्पादन पैदा करता है:

one: open
two: closed
four: open
five: closed

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

    public class Building
    {
        public enum StatusType
        {
            open,
            closed,
            weird,
        };

        public string Name { get; set; }
        public string Status { get; set; }
    }

    public static List <Building> buildingList = new List<Building> ()
    {
        new Building () { Name = "one", Status = "open" },
        new Building () { Name = "two", Status = "closed" },
        new Building () { Name = "three", Status = "weird" },

        new Building () { Name = "four", Status = "open" },
        new Building () { Name = "five", Status = "closed" },
        new Building () { Name = "six", Status = "weird" },
    };

    static void Main (string [] args)
    {
        var statusList = new List<Building.StatusType> () { Building.StatusType.open, Building.StatusType.closed };
        var statusStringList = statusList.ConvertAll <string> (st => st.ToString ());

        var q = from building in buildingList
                where statusStringList.Contains (building.Status)
                select building;

        foreach ( var b in q )
            Console.WriteLine ("{0}: {1}", b.Name, b.Status);

        Console.ReadKey ();
    }

मैंने एक IEnumerable को दूसरे में बदलने के लिए यह एक्सटेंशन विधि बनाई, लेकिन मुझे यकीन नहीं है कि यह कितना कुशल है; यह सिर्फ पर्दे के पीछे एक सूची बना सकता है।

public static IEnumerable <TResult> ConvertEach (IEnumerable <TSource> sources, Func <TSource,TResult> convert)
{
    foreach ( TSource source in sources )
        yield return convert (source);
}

तब आप उस खंड को बदल सकते हैं:

where statusList.ConvertEach <string> (status => status.GetCharValue()).
    Contains (v.Status)

और शुरुआत के List<string>साथ बनाना छोड़ें ConvertAll ()


धन्यवाद लैरी कि काम किया, यहाँ है जो मैं अपने कोड का उल्लेख करके किया था ... लेकिन अगर मैं एक नई सूची बनाने की जरूरत नहीं थी तो यह अच्छा होगा ???? // प्रयोग किया जाता है क्योंकि इसका ILIST क्योंकि और मेरे GetCharValue को चलाता है // यह मेरे char के var statusStringList = building.ToList () के साथ एक "NEW" सूची बनाता है। ConvertAll <char> (st = "st .GetCharValue ()); var test = in v from qry जहाँ statusStringList.Contains (v.Status) v का चयन करता है; सभी काम करता है, जैसा कि मैं कहता हूं कि नई सूची में शामिल नहीं होना या कॉन्टेन्स के अंदर एक लैम्ब्डा का उपयोग करना अच्छा नहीं होगा लेकिन यह संभव नहीं है?
स्मिथ को चिह्नित करें

मुझे लगता है कि स्थिति संपत्ति एक स्ट्रिंग है; इसलिए आपको प्रत्येक तुलना के लिए स्टेटस एनम को स्ट्रिंग्स में बदलना होगा। आप शुरुआत में एक बार उन्हें बदल सकते हैं और इसके साथ हो सकते हैं।
XXXXX

मैंने एक ऐसा संपादन किया है जो प्रश्न को काफी सरल करता है, लेकिन ऐसा करने में, इस उत्तर को क्रमबद्ध कर देता है। इस बारे में क्षमा करें, लेकिन मुझे लगा कि यह समग्र रूप से अधिक अच्छे के लिए है।
मार्क अमेरी

-1

अगर मैं सही ढंग से समझता हूं, तो आपको बिल्डिंग सूची में उस प्रकार (चार मान) को बदलने की जरूरत है जिसे आप बिल्डिंगस्टैटस सूची में स्टोर करते हैं।

(भवन की सूची में प्रत्येक स्थिति के लिए // चरित्र मान //, क्या स्थिति भवन निर्माण सूची में मौजूद है / enum मान //)

public static IQueryable<Building> WithStatus(this IQueryable<Building> qry,  
IList<BuildingStatuses> buildingStatus) 
{ 
    return from v in qry
           where ContainsStatus(v.Status)
           select v;
} 


private bool ContainsStatus(v.Status)
{
    foreach(Enum value in Enum.GetValues(typeof(buildingStatus)))
    {
        If v.Status == value.GetCharValue();
            return true;
    }

    return false;
}

-1; जबकि प्रश्न से मेरे संपादन ने प्रश्न से सभी संदर्भ हटाकर इस उत्तर को थोड़ा अमान्य कर दिया है Building, यह पहले से ही टूट गया था । foreach(Enum value in Enum.GetValues(typeof(buildingStatus)))बकवास है।
मार्क अमेरी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.