Periksa apakah suatu nilai ada dalam array (C #)

109

Bagaimana cara memeriksa apakah suatu nilai ada dalam array di C #?

Seperti, saya ingin membuat array dengan daftar nama printer.

Ini akan diumpankan ke metode, yang akan melihat setiap string secara bergantian, dan jika string tersebut sama dengan nilai dalam array, lakukan tindakan itu.

Sebagai contoh:

string[] printer = {"jupiter", "neptune", "pangea", "mercury", "sonic"};
foreach (p in printer)
{
   PrinterSetup(p);     
}

Ini adalah nama-nama printer, mereka diumpankan ke metode PrinterSetup.

PrinterSetup akan terlihat seperti ini (beberapa pseudocode):

public void PrinterSetup(printer)
{
   if (printer == "jupiter") 
   {
      Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC");
   }
}

Bagaimana if (printer == "jupiter")cara memformat dengan cara yang dikenali C #?

Cecil Rodriguez
sumber
4
Coba berikan nama parameter Anda tipe (string) dan itu akan baik-baik saja.
Jon Skeet
2
Saya agak bingung dengan pertanyaan itu. Apakah Anda bertanya bagaimana cara memeriksa apakah suatu nilai ada dalam array, atau bagaimana melakukan perbandingan string di C #? Jika yang terakhir, Anda akan menggunakan printer.Equals("jupiter"). Jika yang pertama, gunakan linqdanprinter.Contains("jupiter")
perabot baru
@newfurniturey Lumayan ... pertanyaannya bingung, kode contoh tidak sesuai dengan judul, sehingga jawabannya juga bingung; mengapa omong kosong seperti ini mendapat suara positif berada di luar jangkauan saya. Dan tidak perlu melakukan printer.Equals("jupiter")... Kode OP if (printer == "jupiter")berfungsi dengan baik ... selama printerdinyatakan sebagai string, seperti yang dicatat Skeet.
Jim Balter

Jawaban:

231

Tambahkan namespace yang diperlukan

using System.Linq;

Kemudian Anda dapat menggunakan Contains()metode LINQ

string[] printer = {"jupiter", "neptune", "pangea", "mercury", "sonic"};
if(printer.Contains("jupiter"))
{
    Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC"");
}
Dmytro
sumber
2
@ 0A. Jawaban ini menurut saya langsung terbaik sebagai cara yang paling sederhana / terpendek dan terkenal untuk mencapai hal yang sama ( How do I check if a value is in an array in C#?) dan juga efisien. Tidak ada loop tanpa metode tambahan. Hanya namespace ekstra yang bukan hal yang besar.
Sami
6
@ Sami: Linq menggunakan loop secara internal.
2
@ 0A0D Sam mungkin mengacu pada kode tertulis, bukan instruksi yang dikompilasi. Linq menggunakan loop dan metode secara internal, tetapi dari sudut pandang pembuat kode semua yang tersembunyi dan tidak perlu dikhawatirkan.
Dilanggar
1
Kanan @ 0A0D. Maksud saya pembuat kode / pengembang tidak perlu loop kanan. Tentu saja, pemeriksaan dari array membutuhkan loop :)
Sami
3
Ini tentu saja mudah dan direkomendasikan. Jika Anda tidak memiliki akses ke LINQ, atau tidak ingin menggunakan LINQ, Anda dapat mengandalkan beberapa implementasi antarmuka eksplisit dari larik. Sejak .NET 1.1 kami memiliki ((IList)printer).Contains("Jupiter")yang non-generik (mungkin jenis nilai kotak dll.) Dan bekerja bahkan untuk array multi-dimensi. Dan sejak .NET 2.0 kami memiliki lebih banyak keajaiban ((IList<string>)printer).Contains("Jupiter")yang lebih aman untuk jenis. Pendekatan LINQ baru di .NET 3.5.
Jeppe Stig Nielsen
29
   string[] array = { "cat", "dot", "perls" };

// Use Array.Exists in different ways.
bool a = Array.Exists(array, element => element == "perls");
bool b = Array.Exists(array, element => element == "python");
bool c = Array.Exists(array, element => element.StartsWith("d"));
bool d = Array.Exists(array, element => element.StartsWith("x"));

// Display bools.
Console.WriteLine(a);
Console.WriteLine(b);
Console.WriteLine(c);
Console.WriteLine(d);
----------------------------output-----------------------------------

1) Benar 2) Salah 3) Benar 4) Salah


sumber
6
Ini harus menjadi jawaban yang diterima. Jika Anda menggunakan sebuah array, itu tidak sepenuhnya tidak mungkin, kinerja itu penting. Dalam hal ini, Linq seringkali menjadi pilihan yang salah.
Philm
22
if ((new [] {"foo", "bar", "baaz"}).Contains("bar"))
{

}  
Tamu
sumber
Ini adalah contoh umum - dapatkah Anda memberikan contoh yang lebih cocok dengan pertanyaan?
kaz
9
Ini mungkin contoh umum, tetapi itulah yang saya cari.
Berikan Birchmeier
7

Sesuatu seperti ini?

string[] printer = {"jupiter", "neptune", "pangea", "mercury", "sonic"};
PrinterSetup(printer);

// redefine PrinterSetup this way:
public void PrinterSetup(string[] printer)
{
    foreach (p in printer.Where(c => c == "jupiter"))
    {
        Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC"");
    }
}
code4life
sumber
7
    public static bool Contains(Array a, object val)
    {
        return Array.IndexOf(a, val) != -1;
    }
Raz Megrelidze
sumber
2
Saya suka ini. Namun, ini akan gagal jika aarray multidimensi (seperti new string[10, 20, 15]misalnya), dengan pengecualian. Ini juga akan gagal dengan array satu dimensi yang tidak diindeks dari nol (seperti Array.CreateInstance(typeof(string), new[] { 5, }, new[] { -2, }), jarang di C # saya akui), dengan kemungkinan nilai kembali yang salah. Kekurangan ini mudah diperbaiki dengan obat generik:public static bool Contains<TElement>(TElement[] a, TElement val) { return Array.IndexOf(a, val) != -1; }
Jeppe Stig Nielsen
Saya suka ini, tetapi hanya karena ini tanpa Linq dan itu menegaskan bahwa IndexOf adalah satu-satunya yang tersisa untuk digunakan.
Bitterblue
6

Catatan: Pertanyaannya adalah tentang array string. Rutinitas yang disebutkan tidak boleh dicampur dengan metode .Contains dari string tunggal.

Saya ingin menambahkan jawaban tambahan yang mengacu pada versi C # yang berbeda dan karena dua alasan:

  • Jawaban yang diterima membutuhkan Linq yang merupakan idiomatik C # meskipun tidak datang tanpa biaya, dan tidak tersedia dalam C # 2.0 atau lebih rendah. Ketika sebuah array terlibat, kinerja mungkin penting, jadi ada situasi di mana Anda ingin tetap menggunakan metode Array.

  • Tidak ada jawaban yang secara langsung menangani pertanyaan di mana ia diminta juga untuk menempatkan ini dalam suatu fungsi (Karena beberapa jawaban juga mencampur string dengan deretan string, ini tidak sepenuhnya tidak penting).

Array.Exists () adalah metode C # /. NET 2.0 dan tidak membutuhkan Linq. Pencarian dalam array adalah O (n). Untuk akses yang lebih cepat, gunakan HashSet atau koleksi serupa.

Sejak .NET 3.5 ada juga metode umum Array<T>.Exists():

public void PrinterSetup(string[] printer)
{
   if (Array.Exists(printer, x => x == "jupiter"))
   {
      Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC");
   }
}

Anda dapat menulis metode ekstensi sendiri (C # 3.0 dan yang lebih baru) untuk menambahkan gula sintaksis untuk mendapatkan ".Contains" yang sama / serupa seperti untuk string untuk semua larik tanpa menyertakan Linq:

// Using the generic extension method below as requested.
public void PrinterSetup(string[] printer)
{
   if (printer.ArrayContains("jupiter"))
   {
      Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC");
   }
}

public static bool ArrayContains<T>(this T[] thisArray, T searchElement)
{
   // If you want this to find "null" values, you could change the code here
   return Array.Exists<T>(thisArray, x => x.Equals(searchElement));
}

Dalam hal ini ArrayContains()metode ini digunakan dan bukan metode Berisi Linq.

Metode. Berisi yang disebutkan di tempat lain merujuk ke List<T>.Contains(sejak C # 2.0) atau ArrayList.Contains(sejak C # 1.1), tetapi tidak ke array itu sendiri secara langsung.

Philm
sumber
1
Saya menyarankan untuk mengubah nama menjadi ArrayContains () untuk menghindari kebingungan dengan Linq Contains ()
peter.cyc
Saya telah melakukan ini, meskipun ada juga argumen yang menentang: Merupakan ide dasar polimorfisme untuk menggunakan nama yang sama untuk tipe data yang berbeda, Terutama dengan pengaturan Linq dalam pikiran. Menggunakan nama yang berbeda bukanlah polimorf. Tapi kesiapan dan menghindari kesalahpahaman akan menang, saya pikir, jadi, ya.
Philm
4

Anda baru saja melewatkan sesuatu dalam metode Anda:

public void PrinterSetup(string printer)
{
   if (printer == "jupiter") 
   {
      Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC"");
   }
}

Tambahkan saja stringdan Anda akan baik-baik saja.


sumber
3

Tidak terlalu jelas apa masalah Anda, tetapi sepertinya Anda menginginkan sesuatu seperti ini:

    List<string> printer = new List<string>( new [] { "jupiter", "neptune", "pangea", "mercury", "sonic" } );

    if( printer.Exists( p => p.Equals( "jupiter" ) ) )
    {
        ...
    }
Brandon Moretz
sumber
2

Pertimbangkan untuk menggunakan HashSet<T>Kelas demi kinerja pencarian:

Metode ini adalah operasi O (1).

- HashSet<T>.ContainsMetode (T), MSDN .

Sebagai contoh:

class PrinterInstaller
{
    private static readonly HashSet<string> PrinterNames = new HashSet<string>
        {
            "jupiter", "neptune", "pangea", "mercury", "sonic"
        };

    public void Setup(string printerName)
    {
        if (!PrinterNames.Contains(printerName))
        {
            throw new ArgumentException("Unknown printer name", "printerName");
        }
        // ...
    }
}
Sergey Brunov
sumber
1

Sekarang saya mencari lebih dari 2 jam untuk menemukan cara yang baik bagaimana menemukan duplikat dalam daftar dan bagaimana menghapusnya . Inilah jawaban paling sederhana:

//Copy the string array with the filtered data of the analytics db into an list
// a list should be easier to use
List<string> list_filtered_data = new List<string>(analytics_db_filtered_data);

// Get distinct elements and convert into a list again.
List<string> distinct = list_filtered_data.Distinct().ToList();

Outputnya akan terlihat seperti ini: Elemen Duplikat akan dihapus dalam daftar baru yang disebut berbeda!

Ricardo Fercher
sumber