ตรวจสอบว่าค่าอยู่ในอาร์เรย์ (C #)


109

ฉันจะตรวจสอบได้อย่างไรว่าค่าอยู่ในอาร์เรย์ใน C #

เช่นฉันต้องการสร้างอาร์เรย์พร้อมรายชื่อเครื่องพิมพ์

สิ่งเหล่านี้จะถูกป้อนเข้ากับเมธอดซึ่งจะดูที่แต่ละสตริงในทางกลับกันและถ้าสตริงนั้นเหมือนกับค่าในอาร์เรย์ให้ดำเนินการนั้น

ตัวอย่างเช่น:

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

นี่คือชื่อของเครื่องพิมพ์ซึ่งถูกป้อนเข้ากับเมธอด PrinterSetup

PrinterSetup จะมีลักษณะเช่นนี้ (pseudocode บางตัว):

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

ฉันจะจัดรูปแบบif (printer == "jupiter")ให้ C # รับรู้ได้อย่างไร


4
ลองตั้งชื่อพารามิเตอร์ของคุณเป็นประเภท (สตริง) และจะไม่เป็นไร
Jon Skeet

2
ฉันรู้สึกสับสนกับคำถาม คุณกำลังถามวิธีตรวจสอบว่าค่าอยู่ในอาร์เรย์หรือไม่หรือจะทำการเปรียบเทียบสตริงใน C # ได้อย่างไร? ถ้าเป็นอย่างหลังคุณจะใช้printer.Equals("jupiter"). หากเป็นของเดิมให้ใช้linqและprinter.Contains("jupiter")
เฟอร์นิเจอร์ใหม่

@newfurniturey ค่อนข้างมาก ... คำถามสับสนรหัสตัวอย่างไม่ตรงกับชื่อเรื่องและคำตอบก็สับสนเช่นเดียวกัน ทำไมอึแบบนี้ถึงได้รับการโหวตมากกว่าฉัน และไม่จำเป็นต้องทำprinter.Equals("jupiter")... รหัสของ OP ใช้if (printer == "jupiter")งานได้ดี ... ตราบใดที่printerประกาศว่าเป็นสตริงตามที่ Skeet บันทึกไว้
Jim Balter

คำตอบ:


233

เพิ่มเนมสเปซที่จำเป็น

using System.Linq;

จากนั้นคุณสามารถใช้Contains()วิธีlinq

string[] printer = {"jupiter", "neptune", "pangea", "mercury", "sonic"};
if(printer.Contains("jupiter"))
{
    Process.Start("BLAH BLAH CODE TO ADD PRINTER VIA WINDOWS EXEC"");
}

2
@ 0A0D. คำตอบนี้คือฉันคิดว่าวิธีที่ดีที่สุดคือวิธีที่ง่ายที่สุด / สั้นที่สุดและเป็นที่รู้จักกันดีในการบรรลุสิ่งเดียวกัน ( How do I check if a value is in an array in C#?) และมีประสิทธิภาพเช่นกัน ไม่มีลูปไม่มีวิธีพิเศษ เพียงแค่เนมสเปซเป็นพิเศษซึ่งไม่ใช่เรื่องใหญ่
Sami

6
@ ซามิ: Linq ใช้ลูปภายใน

2
@ 0A0D Sam อาจหมายถึงโค้ดที่เขียนไม่ใช่คำสั่งที่รวบรวม Linq ใช้ลูปและวิธีการภายใน แต่จากมุมมองของ coders สิ่งที่ซ่อนอยู่และไม่จำเป็นต้องกังวล
Trisped

1
ขวา @ 0A0D. ฉันหมายความว่า coder / ผู้พัฒนาไม่จำเป็นต้องวนซ้ำ การตรวจสอบนอกหลักสูตรจากอาร์เรย์จำเป็นต้องวนซ้ำ :)
Sami

3
นี่เป็นเรื่องง่ายและแนะนำได้อย่างแน่นอน หากคุณไม่มีสิทธิ์เข้าถึง Linq หรือไม่ต้องการใช้ Linq คุณสามารถพึ่งพาการใช้งานอินเทอร์เฟซที่ชัดเจนของอาร์เรย์ได้ เนื่องจาก. NET 1.1 เรามี((IList)printer).Contains("Jupiter")ซึ่งไม่ใช่แบบทั่วไป (อาจเป็นประเภทค่ากล่องเป็นต้น) และใช้งานได้แม้กระทั่งกับอาร์เรย์หลายมิติ และตั้งแต่. NET 2.0 เรามีความมหัศจรรย์มากขึ้น((IList<string>)printer).Contains("Jupiter")ซึ่งมีความปลอดภัยมากกว่า วิธี Linq เป็นวิธีใหม่ใน. 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) จริง 2) เท็จ 3) จริง 4) เท็จ


6
นี่ควรเป็นคำตอบที่ได้รับการยอมรับ หากคุณใช้อาร์เรย์ก็ไม่น่าจะเป็นไปได้อย่างสมบูรณ์ประสิทธิภาพนั้นมีความสำคัญ ในกรณีนี้ Linq มักเป็นตัวเลือกที่ผิด
Philm

22
if ((new [] {"foo", "bar", "baaz"}).Contains("bar"))
{

}  

นี่เป็นตัวอย่างทั่วไป - คุณสามารถระบุคำถามที่ตรงกับคำถามได้ดีกว่าไหม
kaz

9
อาจเป็นตัวอย่างทั่วไป แต่เป็นสิ่งที่ฉันกำลังมองหา
Grant Birchmeier

7

อะไรทำนองนี้?

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

7
    public static bool Contains(Array a, object val)
    {
        return Array.IndexOf(a, val) != -1;
    }

2
ฉันชอบสิ่งนี้. อย่างไรก็ตามจะล้มเหลวหากaเป็นอาร์เรย์หลายมิติ (เช่นnew string[10, 20, 15]) โดยมีข้อยกเว้น นอกจากนี้ยังจะล้มเหลวด้วยอาร์เรย์มิติเดียวที่ไม่ได้จัดทำดัชนีจากศูนย์ (เช่นArray.CreateInstance(typeof(string), new[] { 5, }, new[] { -2, })หายากใน C # ฉันยอมรับ) โดยอาจมีค่าส่งคืนที่ไม่ถูกต้อง ข้อบกพร่องเหล่านี้แก้ไขได้ง่ายด้วยยาชื่อสามัญ:public static bool Contains<TElement>(TElement[] a, TElement val) { return Array.IndexOf(a, val) != -1; }
Jeppe Stig Nielsen

ฉันชอบสิ่งนี้ แต่เพียงเพราะมันไม่มี Linq และยืนยันว่า IndexOf เป็นสิ่งเดียวที่เหลือให้ใช้
Bitterblue

6

หมายเหตุ: คำถามเกี่ยวกับอาร์เรย์ของสตริง ไม่ควรผสมรูทีนที่กล่าวถึงกับเมธอด. ประกอบด้วยของสตริงเดี่ยว

ฉันต้องการเพิ่มคำตอบเพิ่มเติมที่อ้างถึงเวอร์ชัน C # ที่แตกต่างกันและเนื่องจากเหตุผลสองประการ:

  • คำตอบที่ยอมรับต้องใช้ Linq ซึ่งเป็นสำนวน C # อย่างสมบูรณ์ในขณะที่ไม่ได้มาโดยไม่มีค่าใช้จ่ายและไม่มีใน C # 2.0 หรือต่ำกว่า เมื่ออาร์เรย์มีส่วนเกี่ยวข้องประสิทธิภาพอาจมีความสำคัญดังนั้นจึงมีสถานการณ์ที่คุณต้องการใช้วิธี Array

  • ไม่มีคำตอบใดที่เกี่ยวข้องโดยตรงกับคำถามที่ถูกขอให้ใส่สิ่งนี้ในฟังก์ชัน (เนื่องจากคำตอบบางคำกำลังผสมสตริงกับอาร์เรย์ของสตริงจึงไม่สำคัญอย่างสมบูรณ์)

Array.Exists () เป็นเมธอด C # /. NET 2.0 และไม่จำเป็นต้องใช้ Linq การค้นหาในอาร์เรย์คือ O (n) สำหรับการเข้าถึงที่รวดเร็วยิ่งขึ้นให้ใช้ HashSet หรือคอลเล็กชันที่คล้ายกัน

เนื่องจาก. NET 3.5 ยังมีวิธีการทั่วไป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");
   }
}

คุณสามารถเขียนวิธีการขยายของตัวเอง (C # 3.0 ขึ้นไป) เพื่อเพิ่มน้ำตาลวากยสัมพันธ์เพื่อให้ได้ ".Contains" ที่เหมือนกัน / คล้ายกันสำหรับสตริงสำหรับอาร์เรย์ทั้งหมดโดยไม่รวม 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));
}

ในกรณีนี้ArrayContains()วิธีนี้ใช้ไม่ใช่วิธีการมีของ Linq

อื่น ๆ ที่กล่าวถึงประกอบด้วยวิธีการอ้างถึงList<T>.Contains(ตั้งแต่ C # 2.0) หรือArrayList.Contains(ตั้งแต่ C # 1.1) แต่ไม่ใช่เพื่ออาร์เรย์โดยตรง


1
ฉันขอแนะนำให้เปลี่ยนชื่อเป็น ArrayContains () เพื่อหลีกเลี่ยงความสับสนกับ Linq ประกอบด้วย ()
peter.cyc

ฉันได้ทำสิ่งนี้แล้วแม้ว่าจะมีข้อโต้แย้งเช่นกัน: มันเป็นแนวคิดพื้นฐานของความหลากหลายในการใช้ชื่อเดียวกันสำหรับประเภทข้อมูลที่แตกต่างกันโดยเฉพาะอย่างยิ่งเมื่อคำนึงถึงการตั้งค่า Linq การใช้ชื่อที่แตกต่างกันไม่ใช่ความหลากหลาย แต่การอ่านง่ายและหลีกเลี่ยงความเข้าใจผิดจะชนะฉันคิดว่าใช่
Philm

3

คุณขาดบางอย่างในวิธีการของคุณ:

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

แค่เพิ่มstringแล้วคุณจะสบายดี


3

ยังไม่ชัดเจนว่าปัญหาของคุณคืออะไร แต่ดูเหมือนว่าคุณต้องการสิ่งนี้:

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

    if( printer.Exists( p => p.Equals( "jupiter" ) ) )
    {
        ...
    }

2

พิจารณาใช้HashSet<T>Classเพื่อประโยชน์ในการค้นหา:

วิธีนี้เป็นการดำเนินการ O (1)

- HashSet<T>.Containsวิธีการ (T), MSDN .

ตัวอย่างเช่น:

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");
        }
        // ...
    }
}

1

ฉันค้นหาขณะนี้กว่า 2 ชั่วโมงจะหาวิธีอย่างวิธีการหารายการที่ซ้ำกันในรายการและวิธีการที่จะลบออก นี่คือคำตอบที่ง่ายที่สุด:

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

ผลลัพธ์จะมีลักษณะดังนี้: องค์ประกอบที่ซ้ำกันจะถูกลบออกในรายการใหม่ที่เรียกว่าแตกต่าง!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.