สตริงอยู่ในอาร์เรย์หรือไม่


107

วิธีใดเป็นวิธีที่ดีที่สุดในการstring[]ดูว่ามีองค์ประกอบหรือไม่ นี่เป็นการถ่ายทำครั้งแรกของฉัน แต่บางทีอาจมีบางอย่างที่ฉันมองข้ามไป ขนาดอาร์เรย์จะมีขนาดไม่เกิน 200 องค์ประกอบ

bool isStringInArray(string[] strArray, string key)
{
    for (int i = 0; i <= strArray.Length - 1; i++)
        if (strArray[i] == key)
            return true;
    return false;
}

คำตอบ:


211

เพียงใช้วิธีการมี () ในตัวที่มีอยู่แล้ว:

using System.Linq;

//...

string[] array = { "foo", "bar" };
if (array.Contains("foo")) {
    //...
}

ด้วยเหตุผลบางอย่างเมื่อฉันมองหาวิธีการครั้งแรกฉันไม่พบ ... ขอบคุณ
Brad

4
@ แบรด: นั่นเป็นเพราะวิธีการขยายมาจาก Enumerable
AnthonyWJones

8
ในฐานะซับ(new string[] { "foo", "bar" }).Contains("foo")
Denis V

8
ยิ่งสั้น:new[] { "foo", "bar" }.Contains(foo)
Eric Bole-Feysot

25

ฉันรู้ว่านี่เป็นเรื่องเก่า แต่ฉันต้องการให้ผู้อ่านใหม่รู้ว่ามีวิธีการใหม่ในการทำเช่นนี้โดยใช้วิธีการทั่วไปและวิธีการขยาย

คุณสามารถอ่านโพสต์บล็อกของฉันเพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีการทำสิ่งนี้ แต่แนวคิดหลักคือ:

โดยการเพิ่มวิธีการขยายนี้ในรหัสของคุณ:

public static bool IsIn<T>(this T source, params T[] values)
{
    return values.Contains(source);
}

คุณสามารถทำการค้นหาของคุณได้ดังนี้:

string myStr = "str3"; 
bool found = myStr.IsIn("str1", "str2", "str3", "str4");

ใช้งานได้กับทุกประเภท (ตราบเท่าที่คุณสร้างวิธีการเท่ากับที่ดี) แบบคุ้ม ๆ แน่นอน


ฉันมีบางอย่างเช่นนี้ var xxx = csvData.Rows[0].ItemArray[0].IsIn(".00", "0.0", ".25", "0.5", ".5", ".50", ".75");สิ่งที่ฉันต้องการทำคือดูว่าใครเป็นข้อมูลในคอลัมน์แรกเพื่อดูว่าค่าไม่ได้ลงท้ายด้วยสตริงใด ๆ ต่อไปนี้หรือไม่ .. หากไม่เป็นเช่นนั้นฉันต้องการส่งคืนสตริงที่ระบุว่า มันไม่มีค่า.00ตัวอย่างเช่นการใช้ตัวอย่างของคุณฉันไม่สามารถทำให้อันนี้ใช้งานได้มันค่อนข้างยากกว่านี้เนื่องจากฉันไม่ต้องการคืนบูลฉันเปลี่ยนวิธีการของคุณเพื่อส่งคืนสตริง แต่ก็ยังไม่ได้รับคำแนะนำใด ๆ
MethodMan

ดูเหมือนว่าจะเป็นคำถามในเว็บไซต์ได้ดีกว่า ไปข้างหน้าและอ้างอิงคำตอบนี้หากจำเป็น
Gabriel McAdams

จริงๆแล้วฉันสามารถหาวิธีที่ยอดเยี่ยมในการทำในสิ่งที่ฉันต้องการได้ฉันเขียนบางสิ่งที่จะตรวจสอบว่าค่าของสตริงภายในสำหรับลูปสำหรับ Datatables ItemArray หรือไม่ลงท้ายด้วยค่าใด ๆ ต่อไปนี้ที่ฉันมีในของฉัน สตริง public static bool EndWithValue(this string value, IEnumerable<string> values) { return values.Any(item => value.EndsWith(item)); }
MethodMan

12

คุณอยู่หลังฟังก์ชัน Array.Exists (หรือวิธีการมีส่วนขยายหากคุณใช้. NET 3.5 ซึ่งสะดวกกว่าเล็กน้อย)


3
นี่คือตัวอย่างการทำงานสำหรับ. NET 2.0: if (Array.Exists (arrayToLookThrough, o => o == elementToSearchFor))
Fueled

7

Linq (สำหรับ s & g's):

var test = "This is the string I'm looking for";
var found = strArray.Any(x=>x == test);

หรือขึ้นอยู่กับความต้องการ

var found = strArray.Any(
    x=>x.Equals(test, StringComparison.OrdinalIgnoreCase));

6

อาร์เรย์เรียงลำดับหรือไม่ ถ้าเป็นเช่นนั้นคุณอาจจะทำค้นหาแบบทวิภาค นี่คือการใช้งาน. NET เช่นกัน หากเรียงลำดับอาร์เรย์แล้วการค้นหาแบบไบนารีจะช่วยเพิ่มประสิทธิภาพในการแก้ปัญหาซ้ำ ๆ


2

โดยทั่วไปแล้วอาร์เรย์เป็นโครงสร้างข้อมูลที่ไม่ดีที่จะใช้หากคุณต้องการถามว่ามีออบเจ็กต์ใดอยู่ในคอลเล็กชันหรือไม่

หากคุณจะทำการค้นหาบ่อย ๆ การใช้Dictionary<string, something>อาร์เรย์อาจจะคุ้มค่ากว่า การค้นหาในพจนานุกรมคือ O (1) (เวลาคงที่) ในขณะที่การค้นหาผ่านอาร์เรย์คือ O (N) (ใช้เวลาตามสัดส่วนกับความยาวของอาร์เรย์)

แม้ว่าอาร์เรย์จะมีเพียง 200 รายการ แต่ถ้าคุณทำการค้นหาจำนวนมากเหล่านี้พจนานุกรมก็น่าจะเร็วขึ้น


1
การค้นหาแบบไบนารีคือ O (log n); พจนานุกรมsubtendsจะ O (1) - แต่มีเป็นจำนวนมากของค่าใช้จ่าย; สำหรับการค้นหาขนาดเล็กถึงขนาดกลางการค้นหาเชิงเส้นหรือการค้นหาแบบไบนารีสามารถทำได้ไม่ดี
Marc Gravell

2

ดังที่กล่าวไว้หลายครั้งในเธรดด้านบนขึ้นอยู่กับกรอบการใช้งาน .Net Framework 3 ขึ้นไปมีเมธอด .Contains () หรือ Exists () สำหรับอาร์เรย์ สำหรับเฟรมเวิร์กอื่น ๆ ด้านล่างสามารถทำเคล็ดลับต่อไปนี้แทนการวนลูปผ่านอาร์เรย์ ...

((IList<string>)"Your String Array Here").Contains("Your Search String Here")

ไม่แน่ใจในประสิทธิภาพมากเกินไป ... Dave


1

คุณยังสามารถใช้ LINQ เพื่อวนซ้ำบนอาร์เรย์ หรือคุณสามารถใช้วิธีการค้นหาซึ่งใช้ผู้รับมอบสิทธิ์ในการค้นหา อย่างไรก็ตามฉันคิดว่าวิธีการค้นหานั้นแพงกว่าเล็กน้อยจากนั้นก็วนลูป


วิธีการค้นหาจะเหมือนกับวิธีการ "วนซ้ำ" โดยอัลกอริทึม ค่าใช้จ่ายเพิ่มเติมใด ๆ จะเป็นการสร้างวัตถุบางอย่างและอาจเป็นเลเยอร์หรือสองทิศทาง แต่หากคุณกังวลเกี่ยวกับการเพิ่มประสิทธิภาพสิ่งเหล่านั้นโดยเสียค่าใช้จ่ายในการอ่านคุณจะกังวลเกี่ยวกับสิ่งที่ไม่ถูกต้อง
AwesomeTown

0

สิ่งนี้เร็วกว่าการวนซ้ำผ่านอาร์เรย์ด้วยตนเอง:

static bool isStringInArray(string[] strArray, string key)
    {

        if (strArray.Contains(key))
            return true;
        return false;
    }

การใช้ LINQ นั้นเร็วกว่าการวนซ้ำผ่านสตริงตามที่ทำในตัวอย่าง strArray เนื้อหา (คีย์) เป็นสิ่งที่จำเป็นจริงๆ
Chris Ballance

3
เบื้องหลัง strArray.Contains (คีย์) กำลังจะวนซ้ำอาร์เรย์อยู่แล้ว ... ไม่มีเวทมนตร์ที่เกี่ยวข้องที่จะทำให้คุณไม่ต้องทำการค้นหา O (n)
AwesomeTown

0

หากคุณไม่ต้องการหรือไม่สามารถใช้ Linq ได้คุณสามารถใช้Array.Exists(...);ฟังก์ชันคงที่:

https://msdn.microsoft.com/en-us/library/yw84x8be%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

var arr = new string[]{"bird","foo","cat","dog"};

var catInside = Array.Exists( 
  arr, // your Array
  (s)=>{ return s == "cat"; } // the Predicate
);

เมื่อเพรดิเคตส่งคืนจริงเมื่อ catInside จะเป็นจริงเช่นกัน

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