if (listofelements.Contains(valueFieldValue.ToString()))
{
listofelements[listofelements.IndexOf(valueFieldValue.ToString())] = value.ToString();
}
मैंने ऊपर की तरह बदल दिया है। क्या इसकी तुलना में कोई अन्य सबसे अच्छा तरीका है?
जवाबों:
सूची में सूचकांक खोजने के लिए लैम्ब्डा का उपयोग करें और सूची आइटम को बदलने के लिए इस सूचकांक का उपयोग करें।
List<string> listOfStrings = new List<string> {"abc", "123", "ghi"};
listOfStrings[listOfStrings.FindIndex(ind=>ind.Equals("123"))] = "def";
Equalsपरीक्षण के लिए, अच्छा पुराना IndexOfकाम भी ठीक है, और अधिक संक्षिप्त है - जैसा कि टिम के उत्तर में है ।
आप इसे अधिक पठनीय और अधिक कुशल बना सकते हैं:
string oldValue = valueFieldValue.ToString();
string newValue = value.ToString();
int index = listofelements.IndexOf(oldValue);
if(index != -1)
listofelements[index] = newValue;
यह केवल एक बार सूचकांक के लिए पूछता है। आपका दृष्टिकोण Containsपहले उपयोग करता है जिसमें सभी वस्तुओं (सबसे खराब स्थिति में) को लूप करने की आवश्यकता होती है, फिर आप IndexOfउन वस्तुओं का उपयोग कर रहे हैं जिन्हें फिर से आइटम को एन्यूमरेट करने की आवश्यकता है।
Equalsया आपको केवल उसी संदर्भ में ऑब्जेक्ट मिलेगा। ध्यान दें कि stringएक वस्तु (संदर्भ प्रकार) भी है।
Equals और आपको यह भी याद रखना है कि कभी-कभी आपको उसी समय लागू करना होगाGetHashCode
GetHashCodeयदि आप ओवरराइड करते हैं Equalsलेकिन GetHashCodeइसका उपयोग केवल तभी किया जाता है जब ऑब्जेक्ट किसी सेट (fe Dictionaryया HashSet) में संग्रहीत होता है , इसलिए इसका उपयोग केवल IndexOfया उसके साथ Containsही नहीं किया जाता है Equals।
IndexOfउपयोग करता है EqualityComparer<T>.Default। क्या आप कह रहे हैं कि अंततः item.Equals(target)सूची में प्रत्येक आइटम के लिए कॉल किया जाएगा , और इसलिए rokkuchan के उत्तर के समान ही व्यवहार है?
आप एक तत्व को बदलने के लिए अपनी सूची में दो बार पहुंच रहे हैं। मुझे लगता है कि साधारण forलूप पर्याप्त होना चाहिए:
var key = valueFieldValue.ToString();
for (int i = 0; i < listofelements.Count; i++)
{
if (listofelements[i] == key)
{
listofelements[i] = value.ToString();
break;
}
}
एक्सटेंशन विधियों का उपयोग क्यों नहीं किया जाता है?
निम्नलिखित कोड पर विचार करें:
var intArray = new int[] { 0, 1, 1, 2, 3, 4 };
// Replaces the first occurance and returns the index
var index = intArray.Replace(1, 0);
// {0, 0, 1, 2, 3, 4}; index=1
var stringList = new List<string> { "a", "a", "c", "d"};
stringList.ReplaceAll("a", "b");
// {"b", "b", "c", "d"};
var intEnum = intArray.Select(x => x);
intEnum = intEnum.Replace(0, 1);
// {0, 0, 1, 2, 3, 4} => {1, 1, 1, 2, 3, 4}
स्रोत कोड:
namespace System.Collections.Generic
{
public static class Extensions
{
public static int Replace<T>(this IList<T> source, T oldValue, T newValue)
{
if (source == null)
throw new ArgumentNullException("source");
var index = source.IndexOf(oldValue);
if (index != -1)
source[index] = newValue;
return index;
}
public static void ReplaceAll<T>(this IList<T> source, T oldValue, T newValue)
{
if (source == null)
throw new ArgumentNullException("source");
int index = -1;
do
{
index = source.IndexOf(oldValue);
if (index != -1)
source[index] = newValue;
} while (index != -1);
}
public static IEnumerable<T> Replace<T>(this IEnumerable<T> source, T oldValue, T newValue)
{
if (source == null)
throw new ArgumentNullException("source");
return source.Select(x => EqualityComparer<T>.Default.Equals(x, oldValue) ? newValue : x);
}
}
}
पहले दो तरीकों को संदर्भ प्रकारों की वस्तुओं को बदलने के लिए जोड़ा गया है। बेशक, आप सभी प्रकारों के लिए सिर्फ तीसरी विधि का उपयोग कर सकते हैं।
PS माइक के अवलोकन के लिए धन्यवाद , मैंने रिप्लेसमेंट विधि जोड़ी है।
Tकोई संदर्भ प्रकार हो या नहीं, अप्रासंगिक है। क्या मायने रखता है कि आप सूची को बदलना (बदलना) चाहते हैं, या एक नई सूची वापस करना चाहते हैं। निश्चित रूप से तीसरी विधि मूल सूची में परिवर्तन नहीं होगा, ताकि आप नहीं कर सकते सिर्फ तीसरी विधि का उपयोग करें ... । पहला तरीका वह है जो पूछे गए विशिष्ट प्रश्न का उत्तर देता है। बहुत बढ़िया कोड - अपने तरीके को ठीक करने के तरीके को ठीक करें :)
FindIndexअपने मूल्यों को खोजने और बदलने के लिए लैम्ब्डा का उपयोग करें :
int j = listofelements.FindIndex(i => i.Contains(valueFieldValue.ToString())); //Finds the item index
lstString[j] = lstString[j].Replace(valueFieldValue.ToString(), value.ToString()); //Replaces the item by new value
आप अगले एक्सटेंशन का उपयोग कर सकते हैं जो एक विधेय स्थिति पर आधारित हैं:
/// <summary>
/// Find an index of a first element that satisfies <paramref name="match"/>
/// </summary>
/// <typeparam name="T">Type of elements in the source collection</typeparam>
/// <param name="this">This</param>
/// <param name="match">Match predicate</param>
/// <returns>Zero based index of an element. -1 if there is not such matches</returns>
public static int IndexOf<T>(this IList<T> @this, Predicate<T> match)
{
@this.ThrowIfArgumentIsNull();
match.ThrowIfArgumentIsNull();
for (int i = 0; i < @this.Count; ++i)
if (match(@this[i]))
return i;
return -1;
}
/// <summary>
/// Replace the first occurance of an oldValue which satisfies the <paramref name="removeByCondition"/> by a newValue
/// </summary>
/// <typeparam name="T">Type of elements of a target list</typeparam>
/// <param name="this">Source collection</param>
/// <param name="removeByCondition">A condition which decides is a value should be replaced or not</param>
/// <param name="newValue">A new value instead of replaced</param>
/// <returns>This</returns>
public static IList<T> Replace<T>(this IList<T> @this, Predicate<T> replaceByCondition, T newValue)
{
@this.ThrowIfArgumentIsNull();
removeByCondition.ThrowIfArgumentIsNull();
int index = @this.IndexOf(replaceByCondition);
if (index != -1)
@this[index] = newValue;
return @this;
}
/// <summary>
/// Replace all occurance of values which satisfy the <paramref name="removeByCondition"/> by a newValue
/// </summary>
/// <typeparam name="T">Type of elements of a target list</typeparam>
/// <param name="this">Source collection</param>
/// <param name="removeByCondition">A condition which decides is a value should be replaced or not</param>
/// <param name="newValue">A new value instead of replaced</param>
/// <returns>This</returns>
public static IList<T> ReplaceAll<T>(this IList<T> @this, Predicate<T> replaceByCondition, T newValue)
{
@this.ThrowIfArgumentIsNull();
removeByCondition.ThrowIfArgumentIsNull();
for (int i = 0; i < @this.Count; ++i)
if (replaceByCondition(@this[i]))
@this[i] = newValue;
return @this;
}
नोट: - थ्रॉइफअर्गुमेंटइंसनल एक्सटेंशन के बजाय, आप एक सामान्य दृष्टिकोण का उपयोग कर सकते हैं जैसे:
if (argName == null) throw new ArgumentNullException(nameof(argName));
तो इन एक्सटेंशन के साथ आपका मामला हल किया जा सकता है:
string targetString = valueFieldValue.ToString();
listofelements.Replace(x => x.Equals(targetString), value.ToString());
मुझे नहीं लगता कि यह सबसे अच्छा है या नहीं, लेकिन आप इसे भी उपयोग कर सकते हैं
List<string> data = new List<string>
(new string[] { "Computer", "A", "B", "Computer", "B", "A" });
int[] indexes = Enumerable.Range(0, data.Count).Where
(i => data[i] == "Computer").ToArray();
Array.ForEach(indexes, i => data[i] = "Calculator");
या, रुसियन एल के सुझाव पर निर्माण, यदि आप जिस आइटम को खोज रहे हैं वह सूची में एक से अधिक बार हो सकता है ::
[Extension()]
public void ReplaceAll<T>(List<T> input, T search, T replace)
{
int i = 0;
do {
i = input.FindIndex(i, s => EqualityComparer<T>.Default.Equals(s, search));
if (i > -1) {
FileSystem.input(i) = replace;
continue;
}
break;
} while (true);
}
मैं इसे जल्दी और सरल करने के लिए सबसे अच्छा लगता हूं
सूची में उर आइटम पाते हैं
var d = Details.Where(x => x.ProductID == selectedProduct.ID).SingleOrDefault();करंट से क्लोन बनाएं
OrderDetail dd = d;उर क्लोन अपडेट करें
dd.Quantity++;सूची में सूचकांक खोजें
int idx = Details.IndexOf(d);में स्थापित आइटम निकालें (1)
Details.Remove(d);डालने
if (idx > -1)
Details.Insert(idx, dd);
else
Details.Insert(Details.Count, dd);