2012-05-09 5 views
7

मान लीजिए मैं तार की एक सूची है, इस तरह:एक सूची <String> सुनिश्चित करने के लिए कि कैसे एक क्रम में प्रत्येक स्ट्रिंग ठीक एक बार

var candidates = new List<String> { "Peter", "Chris", "Maggie", "Virginia" }; 

अब मैं यह सत्यापित करने के लिए एक और List<String>, चलो यह list1 कॉल करना चाहते हैं , उनमें से प्रत्येक उम्मीदवार बिल्कुल एक बार शामिल है। मैं यह कैसे कर सकता हूं, संक्षेप में? मुझे लगता है कि मैं Intersect() का उपयोग कर सकता हूं। मैं भी लापता उम्मीदवारों को प्राप्त करना चाहता हूं।

private bool ContainsAllCandidatesOnce(List<String> list1) 
{ 
    ???? 
} 


private IEnumerable<String> MissingCandidates(List<String> list1) 
{ 
    ???? 
} 

आदेश कोई फर्क नहीं पड़ता।

+0

इस सवाल देखें: http://stackoverflow.com/questions/568347/how-do-i-use-linq-to-obtain-a-unique-list-of-properties-from इन प्रकारों या प्रश्नों के लिए –

+0

कृपया उत्तर के साथ प्रश्न प्रदान करें ताकि आप जो पूछ रहे हैं और आपको क्या मिलता है, यह स्पष्ट हो जाता है कि सूची 1 नई सूची {"foo" , "बार"} 'और मैं' नई सूची {"बार", "foo"} 'चाहता हूं। –

उत्तर

5

इस गति के मामले में इष्टतम नहीं हो सकता है, लेकिन दोनों प्रश्नों इतना छोटा हो कि एक ही लाइन पर फिट करने के लिए कर रहे हैं, और समझने में आसान कर रहे हैं:

private bool ContainsAllCandidatesOnce(List<String> list1) 
{ 
    return candidates.All(c => list1.Count(v => v == c) == 1); 
} 

private IEnumerable<String> MissingCandidates(List<String> list1) 
{ 
    return candidates.Where(c => list1.Count(v => v == c) != 1); 
} 
0
private bool ContainsAllCandidatesOnce(List<String> list1) 
    { 
     return list1.Where(s => candidates.Contains(s)).Count() == candidates.Count(); 
    } 

    private IEnumerable<String> MissingCandidates(List<String> list1) 
    { 
     return candidates.Where(s => list1.Count(c => c == s) != 1); 
    } 
1

यह काफी कुशल होना चाहिए:

IEnumerable<string> strings = ... 

var uniqueStrings = from str in strings 
        group str by str into g 
        where g.Count() == 1 
        select g.Key; 

var missingCandidates = candidates.Except(uniqueStrings).ToList(); 
bool isValid = !missingCandidates.Any(); 
  1. दोहराना फ़िल्टर करें।
  2. सुनिश्चित करें कि सभी उम्मीदवार फ़िल्टर किए गए आउट-सेट में होते हैं।
2

यहाँ हम के बारे में Except, Intersect और Distinct बात कर रहे हैं। मैं अभिव्यक्ति के साथ एक लांबा ऑपरेटर का इस्तेमाल कर सकता था लेकिन इसे प्रत्येक आइटम पर लूप करना होगा। वह कार्यक्षमता पूर्वनिर्धारित कार्यों के साथ उपलब्ध है।

अपनी पहली विधि के लिए

var candidates = new List<String> { "Peter", "Chris", "Maggie", "Virginia" }; 

private bool ContainsAllCandidatesOnce(List<String> list1) 
{ 
    list1.Intersect(candidates).Distinct().Any(); 
} 

यह List1 से किसी भी तत्व है जो उम्मीदवारों की सूची में आम में हैं दे देंगे या आप इसे अपने दूसरे के लिए अन्य तरीके से

candidates.Intersect(list1).Distinct().Any(); 

कर सकते हैं विधि

private IEnumerable<String> MissingCandidates(List<String> list1) 
{ 
    list1.Except(candidates).AsEnumerable(); 
} 

यह सूची 1 से सभी तत्वों को हटा देगा जो उम्मीदवारों में हैं। अगर आप इसे

candidates.Except(list1).AsEnumerable(); 
0

सूची के बजाय हैशसेट का उपयोग करने के बारे में कैसे चाहते हैं?

+0

यह बड़ी सूचियों पर अधिक कुशल होगा। – MrWuf

1

ग्रुपजॉइन नौकरी के लिए सही उपकरण है। msdn से:

GroupJoin जिसका अर्थ है कि बाहरी तत्वों से भीतरी से मिलान तत्वों के संग्रह के साथ जोड़ा जाता श्रेणीबद्ध परिणाम का उत्पादन,। GroupJoin आपको अपने परिणामों को बाहरी के प्रत्येक तत्व के लिए मैचों के पूरे सेट पर आधार बनाने में सक्षम बनाता है।

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

तो, ग्रुपजॉइन स्रोत में प्रत्येक आइटम के लिए लक्ष्य से कोई भी मिलान मिलेगा। यदि लक्ष्य में कोई मिलान नहीं मिलता है तो स्रोत में आइटम फ़िल्टर नहीं किए जाते हैं। इसके बजाय वे एक खाली समूह से मेल खाते हैं।

Dictionary<string, int> counts = candidates 
.GroupJoin(
    list1, 
    c => c, 
    s => s, 
    (c, g) => new { Key = c, Count = g.Count() 
) 
.ToDictionary(x => x.Key, x => x.Count); 

List<string> missing = counts.Keys 
    .Where(key => counts[key] == 0) 
    .ToList(); 

List<string> tooMany = counts.Keys 
    .Where(key => 1 < counts[key]) 
    .ToList(); 
-1
private static bool ContainsAllCandidatesOnce(List<string> lotsOfCandidates) 
{ 
    foreach (string candidate in allCandidates) 
    { 
     if (lotsOfCandidates.Count(t => t.Equals(candidate)) != 1) 
     { 
      return false; 
     } 
    } 

    return true; 
} 

private static IEnumerable<string> MissingCandidates(List<string> lotsOfCandidates) 
{ 
    List<string> missingCandidates = new List<string>(); 

    foreach (string candidate in allCandidates) 
    { 
     if (lotsOfCandidates.Count(t => t.Equals(candidate)) != 1) 
     { 
      missingCandidates.Add(candidate); 
     } 
    } 

    return missingCandidates; 
} 
संबंधित मुद्दे