C # में किसी सूची <> में किसी ऑब्जेक्ट को कैसे अपडेट करें


82

मेरे पास एक List<>कस्टम ऑब्जेक्ट है।

मुझे कुछ संपत्ति द्वारा इस सूची में एक ऑब्जेक्ट खोजने की आवश्यकता है जो अद्वितीय है और इस ऑब्जेक्ट की किसी अन्य संपत्ति को अपडेट करें।

इसे करने का सबसे तेज तरीका क्या है?

जवाबों:


109

आप जिस वस्तु को कर सकते हैं उसे पाने के लिए Linq का उपयोग करना:

var obj = myList.FirstOrDefault(x => x.MyProperty == myValue);
if (obj != null) obj.OtherProperty = newValue;

लेकिन इस मामले में आप एक शब्दकोश में सूची को सहेजना चाहते हैं और इसके बजाय इसका उपयोग कर सकते हैं:

// ... define after getting the List/Enumerable/whatever
var dict = myList.ToDictionary(x => x.MyProperty);
// ... somewhere in code
MyObject found;
if (dict.TryGetValue(myValue, out found)) found.OtherProperty = newValue;

4
धन्यवाद CKoenig, क्या इससे objया मान (कॉपी) का संदर्भ मिलेगा ? दूसरे शब्दों में, क्या सूची के अंदर वस्तु बदल जाएगी?
बुर्जुआ

4
मुझे लगता है कि यह काम नहीं करेगा यदि वस्तु टाइप स्ट्रक्चर की है, तो इसे एक क्लास बनाएं :)
सारा एस।

27
क्योंकि आपके पास कस्टम ऑब्जेक्ट्स की एक सूची है (एक वर्ग और एक संरचना नहीं मानकर), आप एक संदर्भ प्रकार के साथ काम कर रहे हैं, यह उस ऑब्जेक्ट का एक संदर्भ होगा और इसे "स्थिर" बनाए रखने के लिए संशोधित करेगा - यह ऑब्जेक्ट को संशोधित करेगा संग्रह।
मैट रॉबर्ट्स

1
यह संदर्भ मिलेगा (इसलिए हां यह सूची में ऑब्जेक्ट होगा) और इसे स्ट्रक्चर्स के साथ भी काम करना चाहिए - लेकिन ईमानदार होने के लिए मुझे वहां सुनिश्चित करने की कोशिश करनी थी - लेकिन मैं यह नहीं देखता कि एटीएम क्यों नहीं
Carsten

2
@CKoenig - यह संरचनों के साथ काम नहीं करेगा, कोड उदाहरण के साथ नीचे एक प्रतिक्रिया प्रदर्शित करने के लिए
मैट रॉबर्ट्स

30

बस CKoenig की प्रतिक्रिया में जोड़ने के लिए। उसका उत्तर तब तक काम करेगा जब तक आप जिस वर्ग के साथ काम कर रहे हैं वह एक संदर्भ प्रकार (एक वर्ग की तरह) है। यदि कस्टम ऑब्जेक्ट एक संरचना थी, तो यह एक मूल्य प्रकार है, और इसके परिणाम .FirstOrDefaultआपको इसकी एक स्थानीय प्रतिलिपि देंगे, जिसका अर्थ है कि यह संग्रह में वापस नहीं आएगा, जैसा कि यह उदाहरण दिखाता है:

struct MyStruct
{
    public int TheValue { get; set; }
}

टेस्ट कोड:

List<MyStruct> coll = new List<MyStruct> {
                                            new MyStruct {TheValue = 10},
                                            new MyStruct {TheValue = 1},
                                            new MyStruct {TheValue = 145},
                                            };
var found = coll.FirstOrDefault(c => c.TheValue == 1);
found.TheValue = 12;

foreach (var myStruct in coll)
{
    Console.WriteLine(myStruct.TheValue);
}
Console.ReadLine();

आउटपुट 10,1,145 है

संरचना को एक वर्ग में बदलें और आउटपुट 10,12,145 है

HTH


ठीक है धन्यवाद। मेरा अनुमान है कि आप एक स्थानीय प्रति के बजाय संरचना का संदर्भ प्राप्त कर सकते हैं।
कार्स्टन

18

या बिना linq के

foreach(MyObject obj in myList)
{
   if(obj.prop == someValue)
   {
     obj.otherProp = newValue;
     break;
   }
}

1
हां, यह स्पष्ट उत्तर है, लेकिन मैं
फॉरच

क्या कोई इस पर टिप्पणी कर सकता है कि ऊपर दिया गया LINQ तरीका वास्तव में इस से अधिक कुशल है?
pseudocoder

6
यदि कोई अंतर है, तो linq संस्करण शायद धीमा है।
Erix

7
@ बूर्जुआ धारणा यह है कि हम वास्तविक लूप को फॉर्च ब्लॉक में होते हुए देख सकते हैं, जबकि लिनक / लैंबडा में हम नहीं करते हैं, इसलिए हम मानते हैं कि फॉर्चून धीमा है और इससे बचने की कोशिश करें। वास्तविकता बहुत तेज़ है / जबकि / छोरों बहुत तेज़ हैं।
harsimranb

अच्छी तरह से धीमी / तेज मुझे पता नहीं है कि ... लेकिन मेरे मामले में मैं वैसे भी छोटे रिकॉर्ड के साथ काम कर रहा था और इसके बारे में ज्यादा नहीं सोचना चाहता था। यह काम किया! ब्रेक के साथ अच्छा स्पर्श;
एंथनी ग्रिग्स


6
var itemIndex = listObject.FindIndex(x => x == SomeSpecialCondition());
var item = listObject.ElementAt(itemIndex);
item.SomePropYouWantToChange = "yourNewValue";

2
सूची से ऑब्जेक्ट को हटाने और इसे फिर से सम्मिलित करने की आवश्यकता नहीं है (बहुत अक्षम)। वस्तुएँ संदर्भ प्रकार हैं। एक बार जब आपके पास ऑब्जेक्ट का संदर्भ होता है, तो ऑब्जेक्ट को अपडेट करें क्योंकि यह सूची में ऑब्जेक्ट के समान एक और एक है।
हम्बड्स

1
एक और सुझाव। FindIndex -1 वापस आ सकता है, जिस स्थिति में ElementAt अपवाद छोड़ देगा।
हम्बड्स

4

आप कुछ कर सकते हैं जैसे:

if (product != null) {
    var products = Repository.Products;
    var indexOf = products.IndexOf(products.Find(p => p.Id == product.Id));
    Repository.Products[indexOf] = product;
    // or 
    Repository.Products[indexOf].prop = product.prop;
}

0

यह आज एक नई खोज थी - कक्षा / संरचना संदर्भ पाठ सीखने के बाद!

आप Linq और "Single" का उपयोग कर सकते हैं यदि आपको पता है कि आइटम मिल जाएगा, क्योंकि सिंगल एक चर देता है ...

myList.Single(x => x.MyProperty == myValue).OtherProperty = newValue;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.