मौजूदा सरणी में c # .net में नया आइटम जोड़ें


134

C # .net में मौजूदा स्ट्रिंग सरणी में नया आइटम कैसे जोड़ें?

मुझे मौजूदा डेटा को संरक्षित करने की आवश्यकता है।

जवाबों:


121

यदि आपको डायनामिक रूप से सरणी की आवश्यकता हो तो मैं एक सूची का उपयोग करूंगा:

List<string> ls = new List<string>();
ls.Add("Hello");

27
और यदि आवश्यक हो, तो अंत में ls.ToArray ()
नारायण

2
प्रश्न में पूछे गए किसी अन्य मैकेनिक का उपयोग करना उत्तर नहीं है।
user11909

@ user2190035: सुनिश्चित नहीं है कि आपको वह विचार कहां मिला है, और 111 लोग जो अपवित्र हैं, वे आपसे असहमत होंगे। यदि आप किसी सरणी का विस्तार करने के लिए एक बेहतर तरीका जानते हैं तो सभी तरीकों से इसे पोस्ट करें। मुझे संदेह है कि आपकी पुन: आवंटन और मैनुअल कॉपी हालांकि एक सूची का उपयोग करने से बेहतर होगी। कभी-कभी जवाब "ऐसा मत करो।"
एड एस।

@ EdS। यह सवाल था कि किसी मौजूदा स्ट्रिंग सरणी में किसी आइटम को कैसे जोड़ा जाए , लेकिन इस उत्तर की कोई सारणी नहीं है, इसके बजाय यह एक नई सूची बनाता है <>। मेरे आवेदन में, मैं सूची को <> में नहीं बदल सकता, इसलिए मुझे एक सरणी (प्रतिलिपि बनाना ...) का आकार बदलना होगा। अली एर्सोज़ के जवाब ने मेरी मदद की।
user11909

@ user2190035: IEnumerable <T> .ToArray ()। मैं हर दिन C # लिखता हूं और मुझे कभी भी इस तरह की एक सरणी का आकार नहीं बदलना पड़ा।
एड एस।

100

यह एक समाधान हो सकता है;

Array.Resize(ref array, newsize);
array[newsize - 1] = "newvalue"

लेकिन डायनामिक साइज़ ऐरे के लिए मैं लिस्ट भी पसंद करूंगा।


@ कोनराड, जो निश्चित रूप से सरणी में डेटा को संरक्षित करेगा।
अली इरोज़

1
यह कुछ समय से अधिक के लिए उपयुक्त नहीं है। क्योंकि 'आकार बदलें' फ़ंक्शन का बहुत बड़ा प्रदर्शन है। एक या दो समय के लिए बग, यह बहुत अच्छा है।
विज्ञापन

53

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तो संभवत: वह डेटा संरचना है जिसे आप चाहते हैं, शुरू करने के लिए सरणी नहीं।


1
बहुत अच्छा +1। मेरे पास जेनेरिक एक्सटेंशन विधि के समान कोड है। मैंने इस उत्तर में कोड को शामिल किया है: stackoverflow.com/a/11035286/673545
dblood

यह बहुत उपयोगी पाया गया है "सी # कोड में एक पंक्ति में एक सरणी में कैसे संलग्न किया जाए" के लिए खोज करते हुए - उम्मीद है कि यह टिप्पणी अगली बार इसे फिर से खोजने के लिए पर्याप्त है।
गैरी

28

बहुत पुराना सवाल है, लेकिन फिर भी इसे जोड़ना चाहते थे।

यदि आप एक-लाइनर की तलाश कर रहे हैं, तो आप नीचे दिए गए कोड का उपयोग कर सकते हैं। यह सूची निर्माणकर्ता को जोड़ती है जो एक गणना योग्य और "नया" (प्रश्न उठाए जाने के बाद) इनिशियल सिंटैक्स को स्वीकार करता है।

myArray = new List<string>(myArray) { "add this" }.ToArray();

27

सी # में सरणी अपरिवर्तनीय हैं , जैसे 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> तत्व जोड़ सकते हैं, इसलिए आपको अपने स्वयं के सूची तत्वों को इस नोड प्रकार में लपेटना होगा। मुझे लगता है कि इसका उपयोग असामान्य है।


मुझे लगता है कि आपका मतलब है Array.Copy
user123456

2
केवल यह उत्तर कि क्यों संभव नहीं है के लिए कुछ जानकारी प्रदान करता है और सिर्फ एक सूची का उपयोग करने का सुझाव नहीं देता है ...
गिल्ड ग्रीन

मेरा मानना ​​है कि Aray.Resizeअपनी सामग्री को खोए बिना किसी सरणी का आकार बदल सकता है। docs.microsoft.com/en-us/dotnet/api/…
AbdelAziz AbdelLatef

25
 Array.Resize(ref youur_array_name, your_array_name.Length + 1);
 your_array_name[your_array_name.Length - 1] = "new item";

7

आप एक सामान्य प्रकार का उपयोग करके एक्सटेंशन विधि बनाने के लिए अपने 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();

धन्यवाद, यह बहुत मददगार था, मैंने एक आइटम को हटाने के लिए एक विकल्प जोड़ा है (मुझे आशा है कि यह आपके साथ ठीक है)।
ताल सहगल

@TalSegal आपका स्वागत है, मेरी खुशी। जैसा कि आप फिट देखते हैं, कोड का उपयोग करें!
dblood

6

ऐरे को अपरिवर्तनीय और निश्चित आकार में रखना बेहतर है।

आप Addद्वारा अनुकरण कर सकते हैं Extension MethodऔरIEnumerable.Concat()

public static class ArrayExtensions
    {
        public static string[] Add(this string[] array, string item)
        {
            return array.Concat(new[] {item}).ToArray();
        }
    }

5

यदि आप सरणियों के साथ बहुत काम कर रहे हैं और किसी कारण से सूचीबद्ध नहीं हैं, तो यह सामान्य टाइप रिटर्न जेनरिक विधि 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;
    }

4

सभी प्रस्तावित उत्तर वही करते हैं जो वे कहते हैं कि वे बचना चाहते हैं, एक नया सरणी बनाकर और केवल खोए हुए माथे के साथ इसमें एक नई प्रविष्टि जोड़ें। LINQ कोई जादू नहीं है, T की सूची एक सरणी है जिसमें कुछ अतिरिक्त स्थान के साथ बफर स्पेस है ताकि आइटम को जोड़ने पर आंतरिक सरणी का आकार बदलने से बचें।

सभी अमूर्त को एक ही मुद्दे को हल करना है, कोई खाली स्लॉट्स के साथ एक सरणी बनाएं जो सभी मानों को रखता है और उन्हें वापस लौटाता है।

यदि आपको लचीलेपन की आवश्यकता है तो एक बड़ी पर्याप्त सूची बना सकते हैं जिसे आप पास करने के लिए उपयोग कर सकते हैं। किसी सरणी का उपयोग करें और उस थ्रेड-सुरक्षित ऑब्जेक्ट को साझा करें। इसके अलावा, नया स्पैन सूची को कॉपी करने के लिए बिना डेटा साझा करने में मदद करता है।

प्रश्न का उत्तर देने के लिए:

Array.Resize(ref myArray, myArray.Length + 1);
data[myArray.Length - 1] = Value;

4

इसलिए यदि आपके पास एक मौजूदा सरणी है, तो मेरा त्वरित सुधार होगा

var tempList = originalArray.ToList();
tempList.Add(newitem);

अब बस मूल सरणी को नए के साथ बदलें

originalArray = tempList.ToArray();

मेरा समाधान हल किया
प्रागुआन

3

.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>इसके बजाय नई विधि का उपयोग कर सकते हैं ।


2

एक सूची का उपयोग करना स्मृति प्रबंधन के लिए आपका सबसे अच्छा विकल्प होगा।


2

एक्सटेंशन पद्धति का उपयोग करने के बारे में क्या? उदाहरण के लिए:

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);

इस बात पर ध्यान दें कि लिनक के यूनियनों के विस्तार के इस व्यवहार (दो सरणियों को एक नए संयोजन में उपयोग किया जाता है), और कार्य करने के लिए लिनक पुस्तकालय की आवश्यकता है।


1

मैं एड से सहमत हूं। C # यह आसान नहीं बनाता है जिस तरह VB ReDim Preserve के साथ करता है। संग्रह के बिना, आपको सरणी को बड़े आकार में कॉपी करना होगा।


2
भगवान का शुक्र है! जब गाली दी जाती है तो रिडिम अविश्वसनीय रूप से धीमा होता है। =)
एड एस।

ReDim Preserveबस एक पेजर में सरणी को कॉपी करता है। कोई चमत्कारी सरणी आकार नहीं है।
ओलिवियर जैकोट-डेसकोम्बर्स


0
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;
    }


0

दुर्भाग्य से एक सूची का उपयोग सभी स्थितियों में काम नहीं करेगा। एक सूची और एक सरणी वास्तव में अलग हैं और 100% विनिमेय नहीं हैं। यह परिस्थितियों पर निर्भर करेगा कि क्या यह एक स्वीकार्य कार्य होगा।


0

चूँकि यह प्रश्न प्रदत्त उत्तर से संतुष्ट नहीं है, मैं इस उत्तर को जोड़ना चाहूँगा :)

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;  
    } 
  }
 }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.