Tambahkan item baru dalam array yang ada di c # .net

134

Bagaimana cara menambahkan item baru dalam array string yang ada di C # .net?

Saya perlu menyimpan data yang ada.

A-Sharabiani
sumber

Jawaban:

121

Saya akan menggunakan Daftar jika Anda membutuhkan array berukuran dinamis:

List<string> ls = new List<string>();
ls.Add("Hello");
Ed S.
sumber
27
Dan jika diperlukan, lakukan ls.ToArray () di akhir
Narayana
2
Menggunakan mekanik lain daripada bertanya dalam pertanyaan bukanlah jawaban.
user11909
@ user2190035: Tidak yakin dari mana Anda mendapatkan ide itu, dan 111 orang yang dipungut suara akan tidak setuju dengan Anda. Jika Anda tahu cara yang lebih baik untuk memperluas array maka dengan segala cara, mempostingnya. Saya ragu alokasi ulang dan salinan manual Anda akan lebih baik daripada menggunakan Daftar. Terkadang jawabannya adalah "jangan lakukan itu."
Ed S.
@ EdS. Pertanyaannya adalah, bagaimana cara menambahkan item ke array string yang ada , tetapi jawaban ini tidak memiliki array sama sekali, sebaliknya ia membuat Daftar baru <>. Dalam aplikasi saya, saya tidak dapat mengubah jenis ke Daftar <>, oleh karena itu saya harus mengubah ukuran array (membuat salinan ...). Jawaban oleh Ali Ersöz membantu saya.
user11909
@ user2190035: IEnumerable <T> .ToArray (). Saya menulis C # setiap hari dan saya tidak pernah harus mengubah ukuran array seperti itu.
Ed S.
100

Itu bisa menjadi solusi;

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

Tetapi untuk array berukuran dinamis saya lebih suka daftar juga.

Ali Ersöz
sumber
@ Konrad, itu pasti akan menyimpan data dalam array.
Ali Ersöz
1
ini tidak cocok untuk lebih dari beberapa kali memohon. karena fungsi 'Resize' memiliki kinerja yang sangat besar. bug untuk satu atau dua kali, ini sangat bagus.
iklan
53

Menggunakan LINQ:

arr = (arr ?? Enumerable.Empty<string>()).Concat(new[] { newitem }).ToArray();

Saya suka menggunakan ini karena itu adalah satu-liner dan sangat nyaman untuk menanamkan dalam pernyataan switch, pernyataan if sederhana, atau lulus sebagai argumen.

EDIT:

Beberapa orang tidak suka new[] { newitem }karena itu menciptakan array sementara yang kecil, satu-item,. Berikut ini adalah versi yang menggunakan Enumerable.Repeatyang tidak memerlukan membuat objek apa pun (setidaknya tidak di permukaan - .NET iterators mungkin membuat banyak objek mesin negara di bawah tabel).

arr = (arr ?? Enumerable.Empty<string>()).Concat(Enumerable.Repeat(newitem,1)).ToArray();

Dan jika Anda yakin bahwa array tidak pernah nullmemulai, Anda dapat menyederhanakannya menjadi:

arr.Concat(Enumerable.Repeat(newitem,1)).ToArray();

Perhatikan bahwa jika Anda ingin menambahkan item ke koleksi yang dipesan, Listmungkin struktur data yang Anda inginkan, bukan sebuah array untuk memulai.

Stephen Chung
sumber
1
+1 sangat bagus. Saya memiliki kode yang mirip dengan metode ekstensi generik. Saya telah memasukkan kode dalam jawaban ini: stackoverflow.com/a/11035286/673545
dblood
Ini sangat berguna menemukannya saat mencari "cara menambahkan ke array dalam satu baris kode di c #" - semoga komentar ini cukup untuk menemukannya lagi di lain waktu.
gary
28

Pertanyaan yang sangat lama, tetapi masih ingin menambahkan ini.

Jika Anda mencari satu-liner, Anda dapat menggunakan kode di bawah ini. Ini menggabungkan konstruktor daftar yang menerima sintaks initializer enumerable dan "baru" (sejak pertanyaan diajukan).

myArray = new List<string>(myArray) { "add this" }.ToArray();
Meringis Putus Asa
sumber
27

Array dalam C # tidak dapat diubah , misalnyastring[] ,int[] . Itu berarti Anda tidak dapat mengubah ukurannya. Anda perlu membuat array baru.

Berikut ini adalah kode untuk 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;
    }
}

Seperti yang Anda lihat itu menciptakan array baru dengan ukuran baru, menyalin konten dari array sumber dan menetapkan referensi ke array baru. Petunjuk untuk ini adalah referensi kata kunci untuk parameter pertama.

Ada daftar yang secara dinamis dapat mengalokasikan slot baru untuk item baru. Ini misalnya Daftar <T> . Ini berisi array yang tidak dapat diubah dan ubah ukurannya saat diperlukan (Daftar <T> bukan implementasi daftar tertaut!). ArrayList adalah hal yang sama tanpa Generics (with array Object ).

LinkedList <T> adalah implementasi daftar tertaut yang nyata. Sayangnya, Anda hanya dapat menambahkan elemen <T> LinkListNode ke daftar, jadi Anda harus membungkus elemen daftar Anda sendiri ke dalam jenis simpul ini. Saya pikir penggunaannya tidak umum.

artur02
sumber
Saya pikir Anda maksud Array.Copy
user123456
2
Hanya jawaban yang memberikan beberapa informasi mengapa itu tidak mungkin dan tidak hanya menyarankan untuk menggunakan daftar ...
Gilad Green
Saya percaya Aray.Resizedapat mengubah ukuran array tanpa kehilangan kontennya. 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";
tmania
sumber
7

Anda dapat memperluas jawaban yang diberikan oleh @Stephen Chung dengan menggunakan logika berbasis LINQ untuk membuat metode ekstensi menggunakan tipe generik.

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

}

Anda kemudian dapat memanggilnya langsung pada array seperti ini.

    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...
    }

Memang, metode AddRangeToArray () tampaknya agak berlebihan karena Anda memiliki fungsi yang sama dengan Concat () tetapi cara ini kode akhir dapat "bekerja" dengan array secara langsung sebagai lawan dari ini:

options = options.Concat(new string[] { "one", "two", "three" }).ToArray();
dblood
sumber
Terima kasih, Ini sangat membantu, saya telah menambahkan opsi untuk menghapus item (saya harap ini tidak masalah bagi Anda).
Tal Segal
@TalSegal, sama-sama, silakan. Gunakan kode sesuai keinginan Anda!
dblood
6

Lebih baik untuk menjaga ukuran Array tetap dan tetap.

Anda dapat mensimulasikan Addoleh Extension MethoddanIEnumerable.Concat()

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

jika Anda banyak bekerja dengan array dan bukan daftar karena alasan tertentu, metode generik yang diketik generik yang diketik ini Addmungkin membantu

    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;
    }
stackuser83
sumber
4

Semua jawaban yang diajukan melakukan hal yang sama dengan apa yang mereka katakan ingin mereka hindari, membuat array baru dan menambahkan entri baru di dalamnya hanya dengan kehilangan lebih banyak overhead. LINQ bukan sihir, daftar T adalah array dengan ruang buffer dengan beberapa ruang ekstra untuk menghindari mengubah ukuran array batin ketika item ditambahkan.

Semua abstraksi harus menyelesaikan masalah yang sama, membuat array tanpa slot kosong yang menampung semua nilai dan mengembalikannya.

Jika Anda memerlukan fleksibilitas, dapat membuat daftar yang cukup besar yang dapat Anda gunakan untuk lulus lalu lakukan itu. lain gunakan array dan bagikan objek yang aman itu. Juga, Rentang baru membantu berbagi data tanpa harus menyalin daftar di sekitar.

Untuk menjawab pertanyaan:

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

Jadi jika Anda memiliki array yang sudah ada, perbaikan cepat saya akan

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

Sekarang ganti saja array asli dengan yang baru

originalArray = tempList.ToArray();
Adi_Pithwa
sumber
Memecahkan
3

Append<TSource>Metode baru telah ditambahkan keIEnumerable<TSource> sejak .NET Framework 4.7.1 dan .NET Core 1.0.

Berikut cara menggunakannya:

var numbers = new [] { "one", "two", "three" };
numbers = numbers.Append("four").ToArray();
Console.WriteLine(string.Join(", ", numbers)); // one, two, three, four

Perhatikan bahwa jika Anda ingin menambahkan elemen di awal array, Anda bisa menggunakan Prepend<TSource>metode baru .

0xced
sumber
2

Menggunakan daftar akan menjadi pilihan terbaik Anda untuk manajemen memori.

Axxelsian
sumber
2

Bagaimana dengan menggunakan metode ekstensi? Misalnya:

public static IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> source, TSource item)
{
    return source.Union(new TSource[] { item });
}

misalnya:

string[] sourceArray = new []
{
    "foo",
    "bar"
}
string additionalItem = "foobar";
string result = sourceArray.Union(additionalItem);

Perhatikan ini meniru perilaku ekstensi Unionion Linq ini (digunakan untuk menggabungkan dua array menjadi yang baru), dan mengharuskan pustaka Linq berfungsi.

William
sumber
1

Saya setuju dengan Ed. C # tidak mempermudah VB dengan ReDim Preserve. Tanpa koleksi, Anda harus menyalin array ke array yang lebih besar.

harpo
sumber
2
Terima kasih Tuhan! ReDim sangat lambat ketika disalahgunakan. =)
Ed S.
ReDim Preservecukup salin array ke lager. Tidak ada perubahan ukuran array yang ajaib.
Olivier Jacot-Descombes
1
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();
Gia Duong Duc Minh
sumber
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;
    }
Dave Blake
sumber
0

Sayangnya menggunakan daftar tidak akan berfungsi dalam semua situasi. Daftar dan array sebenarnya berbeda dan tidak dapat dipertukarkan 100%. Itu akan tergantung pada keadaan jika ini akan menjadi pekerjaan yang dapat diterima.

BOTOL
sumber
0

Karena pertanyaan ini tidak puas dengan jawaban yang diberikan, saya ingin menambahkan jawaban ini :)

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;  
    } 
  }
 }
}
Saif
sumber