2013-09-06 17 views
7

मैं कुछ वर्ग के प्रकार के 2 सूची वस्तु है में स्थानीय चर का उपयोग करने,कैसे एक लैम्ब्डा अभिव्यक्ति

class person 
    { 
     public string id { get; set; } 
     public string name { get; set; } 
    } 

List<person> pr = new List<person>(); 
pr.Add(new person { id = "2", name = "rezoan" }); 
pr.Add(new person { id = "5", name = "marman" }); 
pr.Add(new person { id = "3", name = "prithibi" }); 

List<person> tem = new List<person>(); 
tem.Add(new person { id = "1", name = "rezoan" }); 
tem.Add(new person { id = "2", name = "marman" }); 
tem.Add(new person { id = "1", name = "reja" }); 
tem.Add(new person { id = "3", name = "prithibi" }); 
tem.Add(new person { id = "3", name = "prithibi" }); 

अब मैं से सभी आईडी प्राप्त करने के लिए "जनसंपर्क" ListObject है कि कोई प्रवेश या "tem" ListObejct में प्रविष्टियों की विषम संख्या। लैम्डा का उपयोग करना

HashSet<string> inconsistantIDs = new HashSet<string>(pr.Select(p => p.id).Where(p => tem.FindAll(t => t.id == p).Count == 0 || tem.FindAll(t => t.id == p).Count % 2 != 0)); 

ऐसा करने के लिए मैं का इस्तेमाल किया है, और यह ठीक काम करता है।

लेकिन आप कोड मैं tem.FindAll का इस्तेमाल किया है .Count (टी => == पी t.id) दो बार == 0 और % 2! = 0 साथ comapre करने से देख सकते हैं।

वहाँ किसी भी तरह से एक अस्थायी चर करने के लिए इसे बचाने tem.FindAll (टी => == पी t.id) .Count एक बार और उपयोग करना और फिर == 0 के साथ इस चर तुलना करने के लिए है और % 2! = 0

अधिक बस मैं इसे दो शर्त के लिए एक बार उपयोग करना चाहता हूं।

+0

कृपया के रूप में "का सामना करना पड़ मुद्दा subjjects का उपयोग नहीं करते

अभी आप एक O(n*m) एल्गोरिथ्म, जो O(n+m) को कम किया जा होता है xxx में ", यह Google- लिंक होगा। –

+0

आपको मिल गया @TimSchmelter – Rezoan

उत्तर

14

Use a statement lambda instead of an expression lambda

var inconsistantIDs = new HashSet<string>(
      pr.Select(p => p.id).Where(p => 
        { 
        var count = tem.FindAll(t => t.id == p).Count; 
        return count == 0 || count % 2 != 0; 
        } 
      )); 
+0

हां यह काम करता है। लेकिन "गिनती। गणना% 2! = 0" होना चाहिए "गिनती% 2! = 0"। क्या आप इसे ठीक कर सकते हैं। @Ahmed KRAIEM – Rezoan

+3

'FindAll' के बजाय मैं 'गणना()' का उपयोग करूंगा। पूर्व को प्रत्येक व्यक्ति के लिए एक नया संग्रह बनाने की जरूरत है। –

+0

@Rezoan ठीक किया गया। @ टिम यह सच है। 'var count = tem.Count (t => t.id == p);' –

2
HashSet<string> inconsistantIDs = new HashSet<string>(
    pr.Select(p => new { Id = p.id, Cnt = tem.FindAll(t => t.id == p.id).Count() }) 
     .Where(p => p.Cnt == 0 || p.Cnt % 2 != 0) 
     .Select(p => p.Id); 
+0

धन्यवाद लेकिन यह मुझे "t.id == p" और ".Count()" पर त्रुटि दे रहा है "गणना" होना चाहिए। क्या आप इस मुद्दे को देख सकते हैं। – Rezoan

+0

फिक्स्ड। लेकिन अगर आप इसे समझ में नहीं आते हैं तो मैं इस कोड का उपयोग नहीं करता। –

4

शायद बस:

var query = pr.Where(p => { int c = tem.Count(p2 => p.id == p2.id); return c == 0 || c % 2 != 0; }); 

रिटर्न दो व्यक्तियों:

2 "rezoan" 
5 "marman" 
2

एक तरफ ध्यान दें पर, सख्ती से प्रदर्शन के अनुसार, यदि आप प्रत्येक आईडी के हैश मैपिंग को इसकी गिनती के लिए बनाते हैं और फिर इसे लूप में खोजते हैं तो आपको बेहतर प्रदर्शन मिलेगा।

// create a map (id -> count), O(m) operation 
var dictionary = new Dictionary<string, int>(); 
foreach (var p in tem) 
{ 
    var counter = 0; 
    dictionary.TryGetValue(p.id, out counter); 
    counter++; 
    dictionary[p.id] = counter; 
} 

// search the map, O(n) operation 
var results = new HashSet<string>(); 
foreach (var p in pr) 
{ 
    var counter = 0; 
    dictionary.TryGetValue(p.id, out counter); 
    if (counter == 0 || counter % 2 != 0) 
     results.Add(p.id); 
} 
+0

आपकी मूल्यवान जानकारी के लिए धन्यवाद।+1 @ ग्रू – Rezoan

3

बयान लैम्ब्डा इसके अलावा आप उपयोग कर सकते let clause:

HashSet<string> inconsistantIDs = new HashSet<string>(
    from p in pr 
    let count = tem.FindAll(t => t.id == p).Count 
    where count == 0 || count % 2 != 0 
    select p.id 
); 
संबंधित मुद्दे