NameValueCollection में कुंजी मौजूद है या नहीं इसकी जाँच करें


141

क्या यह जांचने का एक त्वरित और सरल तरीका है कि क्या किसी NameValueCollection में कोई कुंजी मौजूद है, इसके माध्यम से लूपिंग के बिना?

Dictionary.CtaintainsKey () या इसी तरह के कुछ के लिए देख रहे हैं।

इसे हल करने के कई तरीके हैं। बस सोच रहा था कि क्या कोई मेरे दिमाग की खुजली को दूर करने में मदद कर सकता है।


यदि आप कुंजी के आधार पर एक लुकअप करना चाहते हैं तो सिर्फ डिक्शनरी का उपयोग करें .... BTW: आप इस वर्ग पर अनुक्रमणिका का उपयोग कर सकते हैं लेकिन यह स्वयं लूपिंग करेगा - इसलिए कोई लाभ नहीं
Carsten

जवाबों:


181

से MSDN :

यह संपत्ति निम्नलिखित मामलों में शून्य है:

1) यदि निर्दिष्ट कुंजी नहीं मिली है;

तो आप बस:

NameValueCollection collection = ...
string value = collection[key];
if (value == null) // key doesn't exist

2) यदि निर्दिष्ट कुंजी मिली है और उसका संबद्ध मूल्य शून्य है।

collection[key]कॉल base.Get()तब base.FindEntry()जो आंतरिक रूप Hashtableसे प्रदर्शन ओ (1) के साथ उपयोग करता है ।


38
यह गुण निम्न मामलों में शून्य देता है: 1) यदि निर्दिष्ट कुंजी नहीं मिली है; और 2) यदि निर्दिष्ट कुंजी मिली है और उसका संबद्ध मूल्य शून्य है। यह संपत्ति दो मामलों के बीच अंतर नहीं करती है।
स्टीव

1
@ और यही कारण है कि
abatishchev

@ सेव ओपी ऐसी टक्कर के बारे में कुछ नहीं कहता।
8

13
दाएं @abatishchev, हालांकि ओपी का कहना है कि 'अगर कोई मौजूद है तो चेकिंग'। कुंजी के रूप में अशक्त लेना सत्य नहीं है। अंत में समझौता किए बिना कोई जवाब नहीं है (कोई लूप नहीं है, खाली तारों का उपयोग करें)
स्टीव

@abatishchev कि 0बराबरी कहना पसंद है null... sry
Andreas Niedermair

54

इस विधि का उपयोग करें:

private static bool ContainsKey(this NameValueCollection collection, string key)
{
    if (collection.Get(key) == null)
    {
        return collection.AllKeys.Contains(key);
    }

    return true;
}

यह सबसे अधिक कुशल है NameValueCollectionऔर यह निर्भर नहीं करता है कि संग्रह में nullमूल्य हैं या नहीं।


5
using System.Linq;इस समाधान का उपयोग करते समय याद रखें ।
झागुर्ग

14

मुझे नहीं लगता कि इनमें से कोई भी उत्तर काफी सही / इष्टतम है। NameValueCollection न केवल शून्य मानों और लापता मानों के बीच अंतर करता है, यह कुंजी के संबंध में भी असंवेदनशील है। इस प्रकार, मुझे लगता है कि एक पूर्ण समाधान होगा:

public static bool ContainsKey(this NameValueCollection @this, string key)
{
    return @this.Get(key) != null 
        // I'm using Keys instead of AllKeys because AllKeys, being a mutable array,
        // can get out-of-sync if mutated (it weirdly re-syncs when you modify the collection).
        // I'm also not 100% sure that OrdinalIgnoreCase is the right comparer to use here.
        // The MSDN docs only say that the "default" case-insensitive comparer is used
        // but it could be current culture or invariant culture
        || @this.Keys.Cast<string>().Contains(key, StringComparer.OrdinalIgnoreCase);
}

मुझे यह समाधान पसंद है। NameValueCollectionBase स्रोत को देखते हुए, यह InvariantCultureIgnoreCase का उपयोग करने में चूक करता है, हालांकि इसका मतलब यह नहीं है कि NameVueueCollection का एक उदाहरण बनाने के लिए एक अलग वर्ग को इसके बजाय उपयोग करने के लिए पारित नहीं किया जाता है।
लेटेक

12

हां, आप AllKeysसंपत्ति की जांच करने के लिए Linq का उपयोग कर सकते हैं:

using System.Linq;
...
collection.AllKeys.Contains(key);

हालांकि Dictionary<string, string[]>इस उद्देश्य के लिए कहीं अधिक उपयुक्त होगा, शायद एक विस्तार विधि के माध्यम से बनाया गया है:

public static void Dictionary<string, string[]> ToDictionary(this NameValueCollection collection) 
{
    return collection.Cast<string>().ToDictionary(key => key, key => collection.GetValues(key));
}

var dictionary = collection.ToDictionary();
if (dictionary.ContainsKey(key))
{
   ...
}

1
यह पूरे संग्रह पर लूप होगा जो O (n) है। जबकि collection[key]आंतरिक रूप Hashtableसे O (1) का उपयोग होता है
abatishchev

4
@abatishchev वास्तव में, हालांकि, collection[key]कुंजी के मौजूद न होने और उस कुंजी के विरुद्ध एक शून्य मान जमा होने के बीच कोई अंतर नहीं करता है।
रिच ओ'केली

इसके अलावा, आप एक गंदे हैक को रोक सकते हैं और प्रतिबिंब का उपयोग करके हैशटेबल के निजी क्षेत्र को पुनः प्राप्त कर सकते हैं।
abatishchev

मुझे लगता है कि यह एक बहुत ही मूर्खतापूर्ण समाधान है। यदि कोई NameValueCollection का उपयोग कर रहा है, तो यह उन कारणों के लिए संभव है जो शब्दकोश समर्थित नहीं हैं, जैसे कि एक शून्य कुंजी।
क्रिस मैरिसिक

0

आप Getविधि का उपयोग कर सकते हैं और जांच सकते हैं कि विधि nullवापस आ जाएगी nullयदि NameValueCollection में निर्दिष्ट कुंजी नहीं है।

MSDN देखें ।


तुम्हें पता है की जरूरत है indexकी keyविधि कॉल करने के। क्या तुम नहीं?
abatishchev

0

यदि संग्रह का आकार छोटा है, तो आप अमीर द्वारा प्रदान किए गए समाधान के साथ जा सकते हैं। हालांकि, एक बड़े संग्रह का मतलब है कि शब्दकोश की पीढ़ी केवल कुंजी संग्रह की खोज की तुलना में काफी धीमी हो सकती है।

इसके अलावा, यदि आपका उपयोग परिदृश्य समय में विभिन्न बिंदुओं में कुंजियों की खोज कर रहा है, जहां NameValueCollection को संशोधित किया गया है, तो हर बार शब्दकोश बनाने से, कुंजी संग्रह की खोज करने की तुलना में धीमा हो सकता है।


0

यह भी एक नई विधि शुरू करने के बिना एक समाधान हो सकता है:

    item = collection["item"] != null ? collection["item"].ToString() : null;

0

जैसा कि आप संदर्भ स्रोतों में देख सकते हैं, NameValueCollection को विरासत में मिला है NameObjectCollectionBase

तो आप आधार-प्रकार लेते हैं, प्रतिबिंब के माध्यम से निजी हैशटेबल प्राप्त करते हैं, और जांचते हैं कि इसमें एक विशिष्ट कुंजी है या नहीं।

इसके लिए मोनो में काम करने के लिए, आपको यह देखना होगा कि मोनो में हैशटेबल का नाम क्या है, जो कि आप यहाँ देख सकते हैं हैशटेबल (m_ItemsContainer), और मोनो-फ़ील्ड प्राप्त करें, यदि प्रारंभिक ईएनएफओ null है (मोनो- क्रम)।

ऐशे ही

public static class ParameterExtensions
{

    private static System.Reflection.FieldInfo InitFieldInfo()
    {
        System.Type t = typeof(System.Collections.Specialized.NameObjectCollectionBase);
        System.Reflection.FieldInfo fi = t.GetField("_entriesTable", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

        if(fi == null) // Mono
            fi = t.GetField("m_ItemsContainer", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

        return fi;
    }

    private static System.Reflection.FieldInfo m_fi = InitFieldInfo();


    public static bool Contains(this System.Collections.Specialized.NameValueCollection nvc, string key)
    {
        //System.Collections.Specialized.NameValueCollection nvc = new System.Collections.Specialized.NameValueCollection();
        //nvc.Add("hello", "world");
        //nvc.Add("test", "case");

        // The Hashtable is case-INsensitive
        System.Collections.Hashtable ent = (System.Collections.Hashtable)m_fi.GetValue(nvc);
        return ent.ContainsKey(key);
    }
}

अल्ट्रा-प्योर नॉन-रिफ्लेक्टिव .NET 2.0 कोड के लिए, आप हैश-टेबल का उपयोग करने के बजाय कुंजियों पर लूप कर सकते हैं, लेकिन यह धीमा है।

private static bool ContainsKey(System.Collections.Specialized.NameValueCollection nvc, string key)
{
    foreach (string str in nvc.AllKeys)
    {
        if (System.StringComparer.InvariantCultureIgnoreCase.Equals(str, key))
            return true;
    }

    return false;
}

0

VB में यह है:

if not MyNameValueCollection(Key) is Nothing then
.......
end if

C # में बस होना चाहिए:

if (MyNameValueCollection(Key) != null) { }

निश्चित नहीं है कि यह होना चाहिए nullया ""यह मदद करनी चाहिए।


क्षमा करें कि VB में है। C # होना चाहिए अगर (MyNameValueCollection (Key)! = Null) {} निश्चित नहीं है कि यह अशक्त होना चाहिए या "" लेकिन यह मदद करनी चाहिए।
कोडशोएबसे

मेरा मानना ​​है कि सही सिंटैक्स Dictionaryडेटा संरचना के समान है , जैसा कि MyNameValueCollection[Key]इसके बजाय MyNameValueCollection(Key), जो एक विधि कॉल की अपेक्षा करता है।
ब्लेयरगैन् 23

0

मैं इस संग्रह का उपयोग कर रहा हूं, जब मैंने छोटे तत्वों के संग्रह में काम किया।

जहां तत्व बहुत हैं, मुझे लगता है कि "डिक्शनरी" का उपयोग करने की आवश्यकता है। मेरा कोड:

NameValueCollection ProdIdes;
string prodId = _cfg.ProdIdes[key];
if (string.IsNullOrEmpty(prodId))
{
    ......
}

या इसका उपयोग किया जा सकता है:

 string prodId = _cfg.ProdIdes[key] !=null ? "found" : "not found";

0
queryItems.AllKeys.Contains(key)

ध्यान रखें कि कुंजी अद्वितीय नहीं हो सकती है और यह तुलना आमतौर पर संवेदनशील होती है। यदि आप पहली मिलान कुंजी का मूल्य प्राप्त करना चाहते हैं और मामले से परेशान नहीं हैं तो इसका उपयोग करें:

        public string GetQueryValue(string queryKey)
        {
            foreach (string key in QueryItems)
            {
                if(queryKey.Equals(key, StringComparison.OrdinalIgnoreCase))
                    return QueryItems.GetValues(key).First(); // There might be multiple keys of the same name, but just return the first match
            }
            return null;
        }

-1
NameValueCollection n = Request.QueryString;

if (n.HasKeys())
   {
       //something
   }

वापसी मान प्रकार: System.Boolean true अगर NameValueCollection में कुंजियाँ हैं जो अशक्त नहीं हैं; अन्यथा, गलत है। संपर्क


2
हालांकि यह सवाल का जवाब दे सकता है, कुछ स्पष्टीकरण अक्सर सराहना करते हैं, खासकर यह समझाने के लिए कि यह कई अन्य उत्तरों के लिए एक अच्छा विकल्प कैसे हो सकता है।
पच0

यह केवल जाँचता है कि संग्रह में कोई कुंजी है या नहीं। ओपी ने एक निश्चित कुंजी के अस्तित्व के लिए कहा ।
बिल का डिस्क्रिप्शन Bill ’
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.