2010-02-17 25 views
7

मैं हाल ही में LINQ खुद को पढ़ रहा हूं और इसे विभिन्न छोटे पहेली में लागू कर रहा हूं। हालांकि, मैंने जिन समस्याओं में भाग लिया है उनमें से एक यह है कि LINQ-to-ऑब्जेक्ट केवल जेनेरिक संग्रह पर काम करता है। एक सामान्य संग्रह में गैर-जेनेरिक संग्रह को परिवर्तित करने के लिए कोई गुप्त चाल/सर्वोत्तम अभ्यास है?गैर-जेनेरिक संग्रह को सामान्य संग्रह में बदलने का सबसे अच्छा तरीका क्या है?

मेरा वर्तमान कार्यान्वयन गैर-जेनेरिक संग्रह को सरणी में कॉपी करता है, फिर उस पर चलता है, लेकिन मैं सोच रहा था कि कोई बेहतर तरीका है या नहीं?

public static int maxSequence(string str) 
{ 
    MatchCollection matches = Regex.Matches(str, "H+|T+"); 
    Match[] matchArr = new Match[matches.Count]; 
    matches.CopyTo(matchArr, 0); 
    return matchArr 
     .Select(match => match.Value.Length) 
     .OrderByDescending(len => len) 
     .First(); 
} 

उत्तर

10

सबसे आसान तरीका आमतौर पर Cast विस्तार विधि है:

IEnumerable<Match> strongMatches = matches.Cast<Match>(); 

ध्यान दें कि यह आस्थगित और अपने डेटा धाराओं है, तो आप इस तरह के रूप में एक पूर्ण "संग्रह" की जरूरत नहीं है - लेकिन यह LINQ प्रश्नों के लिए एक बिल्कुल सही डेटा स्रोत है। अगर आप एक प्रश्न अभिव्यक्ति में सीमा चर का प्रकार निर्दिष्ट

Cast स्वचालित रूप से कहा जाता है:

तो पूरी तरह से आपकी क्वेरी परिवर्तित करने के लिए:

public static int MaxSequence(string str) 
{  
    return (from Match match in Regex.Matches(str, "H+|T+") 
      select match.Value.Length into matchLength 
      orderby matchLength descending 
      select matchLength).First(); 
} 

या

public static int MaxSequence(string str) 
{  
    MatchCollection matches = Regex.Matches(str, "H+|T+"); 
    return matches.Cast<Match>() 
        .Select(match => match.Value.Length) 
        .OrderByDescending(len => len) 
        .First(); 
} 

वास्तव में , आपको OrderByDescending और फिर First पर कॉल करने की आवश्यकता नहीं है - आप केवल अधिकतम मान चाहते हैं, जोविधि आपको प्राप्त करती है। और भी बेहतर, यह आप मूल्य आप को खोजने की कोशिश कर रहे करने के लिए एक स्रोत तत्व प्रकार से एक प्रक्षेपण निर्दिष्ट करते हैं, तो आप Select बिना भी कर सकते हैं कर सकते हैं:

public static int MaxSequence(string str) 
{  
    MatchCollection matches = Regex.Matches(str, "H+|T+"); 
    return matches.Cast<Match>() 
        .Max(match => match.Value.Length); 
} 

आप एक संग्रह जो कुछ है है, तो सही प्रकार के तत्व लेकिन कुछ जो नहीं हो सकते हैं, आप इसके बजाय OfType का उपयोग कर सकते हैं। Cast अपवाद फेंकता है जब यह "गलत" प्रकार की वस्तु का सामना करता है; OfType बस इसे छोड़ देता है।

+0

बहुत बहुत धन्यवाद! मुझे यकीन नहीं है कि मैंने दस्तावेज़ में उस विधि को कैसे याद किया, लेकिन यह वही है जो मैं ढूंढ रहा था! मैक्स() का उपयोग करने पर टिप के लिए भी धन्यवाद – guhou

1

आप Cast या OfType को IEnumerable पर कनवर्ट करने के लिए उपयोग कर सकते हैं। Cast अवैध कास्ट फेंक देगा यदि तत्व को निर्दिष्ट प्रकार पर नहीं डाला जा सकता है जबकि OfType किसी भी तत्व को छोड़ देगा जिसे परिवर्तित नहीं किया जा सकता है।

संबंधित मुद्दे