2013-01-16 9 views
5

मेरे पास दो प्रश्न हैं, प्रत्येक ऑब्जेक्ट्स की सूची लौटा रहा है।किसी दिए गए प्रॉपर्टी पर दो सूचियों को मर्ज कैसे करें

List<A> list1 = (....query...) 
List<A> list2 = (....query...) 

"ए" एक ऑब्जेक्ट मॉडल है।

दोनों प्रश्न लगभग एक ही वस्तुएं लौटाते हैं लेकिन विभिन्न गुणों के साथ सेट करते हैं।

List<A> finalLis = list1 join list2 on elemList1.somePropID == elemList2.somePropID 

सरल सी # शैली में यह कुछ इस तरह होगा:

मैं डुप्लिकेट निकालना चाहते हैं उन्हें एक ही सूची कुछ इस तरह वस्तु ए की संपत्ति के आधार पर

असल में विलय:

foreach(elem1 : list1) { 
    foreach(elem2: list1) { 
     if(elem1.someID == elem2.someID) { 
      elem1.someProp = elem2.someProp 
      elem1.otherProp = elem2.otherProp 
     } 
    } 
} 

मैं इसे इस तरह से नहीं करना चाहता क्योंकि मुझे यकीन है कि linq में एक और अधिक शानदार तरीका है।

यदि आपके कोई सुझाव हैं तो कृपया मुझे बताएं।

+0

आप दूसरा संग्रह, कि पहला संग्रह में किसी भी आइटम आईडी से मेल नहीं खाता है, परिणाम में सेट से आइटम नहीं हैं करना चाहते हैं? – mipe34

+0

नहीं .... पहली सूची में तत्व लगभग दूसरी सूची में समान तत्व हैं। विचार यह है कि पहली सूची में कुछ गुण सेट नहीं होते हैं, लेकिन वे मान उनके समकक्षों में पाए जा सकते हैं। अंतिम सूची पहली सूची है लेकिन सभी गुणों के साथ – cmg

उत्तर

1

Linq चयन करने के साथ तुम्हारी मदद लेकिन अद्यतन करने के साथ नहीं कर सकते। तो आप foreach कथन से छुटकारा नहीं पाएंगे। तो अपने काम के लिए इस तरह LINQ के साथ लिखा जा सकता है:

//the query is like LEFT JOIN in SQL 
var query = from x in list1 
      join y in list2 on x.IDItem equals y.IDItem 
      into z 
      from q in z.DefaultIfEmpty() 
      select new {IOne = x, ITwo = q}; 
foreach (var pair in query) 
{ 
    if (pair.ITwo != null) // && pair.IOne.OneProperty != null 
     pair.IOne.OneProperty = pair.ITwo.TwoProperty; 
} 

var resultList = query.Select(x => x.IOne).ToList(); 

आप परिणामों here देख सकते हैं।

0

इस प्रयास करें:

List<A> list = (from e1 in list1 
      join e2 in list2 
      on e1.ID equals e2.ID 
      select new A 
      { 
       ID = l2.ID, 
       someProp1 = l2.someProp1, 
       someProp2 = l2.someProp2 
      }).ToList(); 

तो फिर तुम सभी तत्वों के साथ एक तीसरी सूची के लिए होगा।

यह लिंक मदद कर सकता है: LINQ Join 2 List<T>s

+1

सेट किया गया है इसमें प्रत्येक सूची (अद्वितीय आईडी के साथ) से अद्वितीय ऑब्जेक्ट शामिल नहीं होंगे। इसके अलावा यह मौजूदा अद्यतन करने की बजाय नई वस्तुओं को बनाएगा। –

+0

लेकिन उन्होंने कहा कि अंतर कुछ गुण हैं जो सूची 1 पर सेट नहीं हैं और सूची 2 पर सेट हैं। और जिस तरह से कोड नमूना लिखा गया था, मैंने सोचा कि वह तीसरी सूची चाहता था। –

0

Linq क्वेरी करने के लिए, नहीं अद्यतन करने है। आप शामिल होने को सरल बना सकते हैं लेकिन आपको अपडेट करने के लिए अभी भी लूप की आवश्यकता होगी।

कुछ की तरह:

List<A> finalList = 
    from item1 in list1 
    join item2 in list2 on item1.somePropID equals item2.somePropID 
    select new{Item1 = item1, Item2 = item2}; 

foreach(var item in finalList) 
{ 
    item.Item2.someProp1 = item.Item1.someProp1; 
    item.Item2.someProp2 = item.Item1.someProp2; 
} 
+1

वही बात - शामिल नहीं आईडी अंतिम सूची में गायब हैं। –

+0

ठीक है मैंने उस टिप्पणी को नहीं देखा जो समझाया गया है। –

0

LINQ का उपयोग करना सही है।

यहां दिए गए उत्तर दिए गए सी # स्निपेट के समतुल्य हैं, इसके अलावा स्निपेट बहुत अक्षम है और सूची 1 का कारण बन जाएगा। लम्बाई * सूची 2। लम्बाई संचालन।

LINQ जॉइन का उपयोग करना अधिक कुशल है और परिणाम लगभग 1 में सूचीबद्ध हैं। लम्बाई + सूची 2। लम्बाई संचालन।

इसका कारण यह है उसकी पहचान पर शामिल होने के एक शब्दकोश

// create a dict so that you can lookup things in item1 based on id 
var list1IdToADict = list1.ToDictionary(a => a.id); 

//filter out things not in both lists (join on there id) 
var joinedList2 = list2.Where(a => list1IdToADict.ContainsKey(a.id)); 

अन्य उत्तर का उपयोग कर कुछ इस तरह करना होगा अधिक elagant हैं, लेकिन आप

foreach(var a in joinedList2){ 
    a.someProp = list1IdToADict[a.id].someProp; 
    a.otherProp = list1IdToADict[a.id].otherProp; 
} 
साथ खत्म हो सकता है अगर आप इसे इस तरह से करना चाहता था
0

List<T> पर कोई भी समाधान एन * लॉग (एन) पर सबसे अच्छा प्रदर्शन करेगा क्योंकि सूचियों को क्रमबद्ध करने की आवश्यकता है।

अपने मॉडल पर समानता सदस्यों को लागू करें और इसके बजाय HashSet<T> का उपयोग करें।

यह जटिलता और आवंटन दोनों में इष्टतम है।

var set1 = new HashSet<Model> 
{ 
    new Model(0, "000"), 
    new Model(2, "222"), 
    new Model(4, "444"), 
}; 

var set2 = new HashSet<Model> 
{ 
    new Model(1, "111"), 
    new Model(2, "2222"), 
    new Model(3, "333"), 
}; 

set1.ExceptWith(set2); 
set1.UnionWith(set2); 

जोड़ने के लिए, यह ओवरराइटिंग परिणाम सेट के रूप में सेट का उपयोग करने के लिए तेजी से हो जाएगा।

set2.UnionWith(set1); 

कक्षा Model ऊपर दिए उदाहरण में:

class Model 
{ 
    public readonly int Id; 
    public string Data; 

    public Model(int id, string data) 
    { 
     Id = id; 
     Data = data; 
    } 

    public override int GetHashCode() 
    { 
     return Id; 
    } 

    protected bool Equals(Model other) 
    { 
     return Id == other.Id; 
    } 

    public override bool Equals(object obj) 
    { 
     if (ReferenceEquals(null, obj)) return false; 
     if (ReferenceEquals(this, obj)) return true; 
     return obj.GetType() == GetType() && Equals((Model) obj); 
    } 
} 
संबंधित मुद्दे