C # .net में मौजूदा स्ट्रिंग सरणी में नया आइटम कैसे जोड़ें?
मुझे मौजूदा डेटा को संरक्षित करने की आवश्यकता है।
C # .net में मौजूदा स्ट्रिंग सरणी में नया आइटम कैसे जोड़ें?
मुझे मौजूदा डेटा को संरक्षित करने की आवश्यकता है।
जवाबों:
यदि आपको डायनामिक रूप से सरणी की आवश्यकता हो तो मैं एक सूची का उपयोग करूंगा:
List<string> ls = new List<string>();
ls.Add("Hello");
यह एक समाधान हो सकता है;
Array.Resize(ref array, newsize);
array[newsize - 1] = "newvalue"
लेकिन डायनामिक साइज़ ऐरे के लिए मैं लिस्ट भी पसंद करूंगा।
LINQ का उपयोग करना:
arr = (arr ?? Enumerable.Empty<string>()).Concat(new[] { newitem }).ToArray();
मुझे यह पसंद है क्योंकि यह एक एक-लाइनर है और एक स्विच स्टेटमेंट में एम्बेड करने के लिए बहुत आसान है, एक साधारण इफ-स्टेटमेंट है, या तर्क के रूप में पास करें।
संपादित करें:
कुछ लोगों को पसंद नहीं है new[] { newitem }क्योंकि यह एक छोटा, एक आइटम, अस्थायी सरणी बनाता है। यहां एक संस्करण का उपयोग किया गया है Enumerable.Repeatजिसे किसी भी वस्तु को बनाने की आवश्यकता नहीं है (कम से कम सतह पर नहीं - .NET पुनरावृत्तियां संभवतः तालिका के तहत राज्य मशीन ऑब्जेक्ट का एक गुच्छा बनाते हैं)।
arr = (arr ?? Enumerable.Empty<string>()).Concat(Enumerable.Repeat(newitem,1)).ToArray();
और अगर आप सुनिश्चित हैं कि सरणी को कभी भी nullशुरू नहीं करना है, तो आप इसे सरल कर सकते हैं:
arr.Concat(Enumerable.Repeat(newitem,1)).ToArray();
ध्यान दें कि यदि आप किसी ऑर्डर किए गए संग्रह में आइटम जोड़ना चाहते हैं, Listतो संभवत: वह डेटा संरचना है जिसे आप चाहते हैं, शुरू करने के लिए सरणी नहीं।
बहुत पुराना सवाल है, लेकिन फिर भी इसे जोड़ना चाहते थे।
यदि आप एक-लाइनर की तलाश कर रहे हैं, तो आप नीचे दिए गए कोड का उपयोग कर सकते हैं। यह सूची निर्माणकर्ता को जोड़ती है जो एक गणना योग्य और "नया" (प्रश्न उठाए जाने के बाद) इनिशियल सिंटैक्स को स्वीकार करता है।
myArray = new List<string>(myArray) { "add this" }.ToArray();
सी # में सरणी अपरिवर्तनीय हैं , जैसे string[], int[]। इसका मतलब है कि आप उनका आकार नहीं बदल सकते। आपको एक नया ऐरे बनाना होगा।
यहाँ Array.Resize के लिए कोड है :
public static void Resize<T>(ref T[] array, int newSize)
{
if (newSize < 0)
{
throw new ArgumentOutOfRangeException("newSize", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
T[] sourceArray = array;
if (sourceArray == null)
{
array = new T[newSize];
}
else if (sourceArray.Length != newSize)
{
T[] destinationArray = new T[newSize];
Copy(sourceArray, 0, destinationArray, 0, (sourceArray.Length > newSize) ? newSize : sourceArray.Length);
array = destinationArray;
}
}
जैसा कि आप देख सकते हैं कि यह नए आकार के साथ एक नया सरणी बनाता है, स्रोत सरणी की सामग्री की प्रतिलिपि बनाता है और नए सरणी का संदर्भ सेट करता है। इसके लिए संकेत पहले पैरामीटर के लिए रेफरी कीवर्ड है।
ऐसी सूचियां हैं जो गतिशील रूप से नई वस्तुओं के लिए नए स्लॉट आवंटित कर सकती हैं । यह उदाहरण सूची <T> है । इनमें अपरिवर्तनीय सरणियाँ होती हैं और आवश्यकता होने पर उनका आकार बदल देते हैं (सूची <T> लिंक की गई कार्यान्वयन सूची नहीं है!)। ArrayList जेनेरिक ( ऑब्जेक्ट सरणी के साथ ) के बिना एक ही बात है ।
लिंक्डलिस्ट <टी> एक वास्तविक लिंक्ड सूची कार्यान्वयन है। दुर्भाग्य से आप सूची में केवल LinkListNode <T> तत्व जोड़ सकते हैं, इसलिए आपको अपने स्वयं के सूची तत्वों को इस नोड प्रकार में लपेटना होगा। मुझे लगता है कि इसका उपयोग असामान्य है।
Aray.Resizeअपनी सामग्री को खोए बिना किसी सरणी का आकार बदल सकता है। docs.microsoft.com/en-us/dotnet/api/…
आप एक सामान्य प्रकार का उपयोग करके एक्सटेंशन विधि बनाने के लिए अपने LINQ आधारित तर्क का उपयोग करके @Stephen चुंग द्वारा प्रदान किए गए उत्तर पर विस्तार कर सकते हैं।
public static class CollectionHelper
{
public static IEnumerable<T> Add<T>(this IEnumerable<T> sequence, T item)
{
return (sequence ?? Enumerable.Empty<T>()).Concat(new[] { item });
}
public static T[] AddRangeToArray<T>(this T[] sequence, T[] items)
{
return (sequence ?? Enumerable.Empty<T>()).Concat(items).ToArray();
}
public static T[] AddToArray<T>(this T[] sequence, T item)
{
return Add(sequence, item).ToArray();
}
}
फिर आप इसे इस तरह से सीधे सरणी पर कॉल कर सकते हैं।
public void AddToArray(string[] options)
{
// Add one item
options = options.AddToArray("New Item");
// Add a
options = options.AddRangeToArray(new string[] { "one", "two", "three" });
// Do stuff...
}
निश्चित रूप से, AddRangeToArray () विधि थोड़ी सी ओवरकिल लगती है क्योंकि आपके पास Concat () के साथ समान कार्यक्षमता है, लेकिन इस तरह अंतिम कोड सरणी के साथ सीधे "काम" कर सकता है:
options = options.Concat(new string[] { "one", "two", "three" }).ToArray();
यदि आप सरणियों के साथ बहुत काम कर रहे हैं और किसी कारण से सूचीबद्ध नहीं हैं, तो यह सामान्य टाइप रिटर्न जेनरिक विधि Addमदद कर सकती है
public static T[] Add<T>(T[] array, T item)
{
T[] returnarray = new T[array.Length + 1];
for (int i = 0; i < array.Length; i++)
{
returnarray[i] = array[i];
}
returnarray[array.Length] = item;
return returnarray;
}
सभी प्रस्तावित उत्तर वही करते हैं जो वे कहते हैं कि वे बचना चाहते हैं, एक नया सरणी बनाकर और केवल खोए हुए माथे के साथ इसमें एक नई प्रविष्टि जोड़ें। LINQ कोई जादू नहीं है, T की सूची एक सरणी है जिसमें कुछ अतिरिक्त स्थान के साथ बफर स्पेस है ताकि आइटम को जोड़ने पर आंतरिक सरणी का आकार बदलने से बचें।
सभी अमूर्त को एक ही मुद्दे को हल करना है, कोई खाली स्लॉट्स के साथ एक सरणी बनाएं जो सभी मानों को रखता है और उन्हें वापस लौटाता है।
यदि आपको लचीलेपन की आवश्यकता है तो एक बड़ी पर्याप्त सूची बना सकते हैं जिसे आप पास करने के लिए उपयोग कर सकते हैं। किसी सरणी का उपयोग करें और उस थ्रेड-सुरक्षित ऑब्जेक्ट को साझा करें। इसके अलावा, नया स्पैन सूची को कॉपी करने के लिए बिना डेटा साझा करने में मदद करता है।
प्रश्न का उत्तर देने के लिए:
Array.Resize(ref myArray, myArray.Length + 1);
data[myArray.Length - 1] = Value;
इसलिए यदि आपके पास एक मौजूदा सरणी है, तो मेरा त्वरित सुधार होगा
var tempList = originalArray.ToList();
tempList.Add(newitem);
अब बस मूल सरणी को नए के साथ बदलें
originalArray = tempList.ToArray();
.NET फ्रेमवर्क 4.7.1 और .NET कोर 1.0 से एक नया Append<TSource>तरीका जोड़ा गया है IEnumerable<TSource>।
यहाँ इसका उपयोग कैसे किया जाता है:
var numbers = new [] { "one", "two", "three" };
numbers = numbers.Append("four").ToArray();
Console.WriteLine(string.Join(", ", numbers)); // one, two, three, four
ध्यान दें कि यदि आप सरणी की शुरुआत में तत्व जोड़ना चाहते हैं, तो आप Prepend<TSource>इसके बजाय नई विधि का उपयोग कर सकते हैं ।
एक्सटेंशन पद्धति का उपयोग करने के बारे में क्या? उदाहरण के लिए:
public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> source, TSource item)
{
return source.Union(new TSource[] { item });
}
उदाहरण के लिए:
string[] sourceArray = new []
{
"foo",
"bar"
}
string additionalItem = "foobar";
string result = sourceArray.Union(additionalItem);
इस बात पर ध्यान दें कि लिनक के यूनियनों के विस्तार के इस व्यवहार (दो सरणियों को एक नए संयोजन में उपयोग किया जाता है), और कार्य करने के लिए लिनक पुस्तकालय की आवश्यकता है।
मैं एड से सहमत हूं। C # यह आसान नहीं बनाता है जिस तरह VB ReDim Preserve के साथ करता है। संग्रह के बिना, आपको सरणी को बड़े आकार में कॉपी करना होगा।
ReDim Preserveबस एक पेजर में सरणी को कॉपी करता है। कोई चमत्कारी सरणी आकार नहीं है।
string str = "string ";
List<string> li_str = new List<string>();
for (int k = 0; k < 100; i++ )
li_str.Add(str+k.ToString());
string[] arr_str = li_str.ToArray();
private static string[] GetMergedArray(string[] originalArray, string[] newArray)
{
int startIndexForNewArray = originalArray.Length;
Array.Resize<string>(ref originalArray, originalArray.Length + newArray.Length);
newArray.CopyTo(originalArray, startIndexForNewArray);
return originalArray;
}
स्ट्रिंगर बिल्डर क्लास का उपयोग करके क्यों न देखें । इसमें .insert और .append जैसे तरीके हैं। आप इसके बारे में और अधिक यहाँ पढ़ सकते हैं: http://msdn.microsoft.com/en-us/library/2839d5h5(v=vs.71).aspx
चूँकि यह प्रश्न प्रदत्त उत्तर से संतुष्ट नहीं है, मैं इस उत्तर को जोड़ना चाहूँगा :)
public class CustomArrayList<T>
{
private T[] arr; private int count;
public int Count
{
get
{
return this.count;
}
}
private const int INITIAL_CAPACITY = 4;
public CustomArrayList(int capacity = INITIAL_CAPACITY)
{
this.arr = new T[capacity]; this.count = 0;
}
public void Add(T item)
{
GrowIfArrIsFull();
this.arr[this.count] = item; this.count++;
}
public void Insert(int index, T item)
{
if (index > this.count || index < 0)
{
throw new IndexOutOfRangeException( "Invalid index: " + index);
}
GrowIfArrIsFull();
Array.Copy(this.arr, index, this.arr, index + 1, this.count - index);
this.arr[index] = item; this.count++; }
private void GrowIfArrIsFull()
{
if (this.count + 1 > this.arr.Length)
{
T[] extendedArr = new T[this.arr.Length * 2];
Array.Copy(this.arr, extendedArr, this.count);
this.arr = extendedArr;
}
}
}
}