การค้นหาว่ามีค่าอยู่ในรายการของวัตถุโดยใช้ Linq


228

บอกว่าผมได้เรียนซึ่งมีคุณสมบัติCustomer จากนั้นฉันมีFirstNameList<Customer>

สามารถใช้ LINQ เพื่อค้นหาว่ารายชื่อมีลูกค้าด้วยFirstname = 'John'คำสั่งเดียว .. ได้อย่างไร?

คำตอบ:


459

LINQ กำหนดวิธีการขยายที่สมบูรณ์แบบสำหรับการแก้ปัญหาที่แน่นอนนี้:

using System.Linq;
...
    bool has = list.Any(cus => cus.FirstName == "John");

ตรวจสอบให้แน่ใจว่าคุณอ้างอิง System.Core.dll นั่นคือที่ LINQ อาศัยอยู่


24
มีอะไรดีฉันสงสัยว่านักพัฒนาจำนวนมากใช้ Count เมื่อใดที่ควรใช้ Any
RichardOD

12
คุณยังสามารถทำการค้นหาแบบตัวพิมพ์เล็กและตัวพิมพ์ใหญ่: cus => cus.FirstName.Equals ("John", StringComparison.CurrentCultureIgnoreCase)
jmservera

1
ฉันรู้ว่านี่เป็นคำถามเก่า แต่ทำไมเราไม่ใช้วิธีการที่มีอยู่ มองตามที่ถูกสร้างขึ้นเพื่อดูว่ามีสิ่งต่าง ๆ หรือไม่
Blackunknown

6
เพราะคอลเลคชั่นไม่ได้มีอยู่ทั้งหมดและมันไม่ได้แสดงออกแลมบ์ดา แต่เป็นวัตถุที่เรากำลังมองหา
zvolkov

1
@zvolkov ความคิดใด ๆ ที่ resharper ของฉันแนะนำให้ฉันใช้บูลมี = list.All (cus => cus.FirstName! = "John"); เป็นสิ่งที่ดีที่สุด?
Gullu

105

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

Customer customer = list.FirstOrDefault(cus => cus.FirstName == "John");
if (customer != null)
{
    // Use customer
}

ฉันรู้ว่านี่ไม่ใช่สิ่งที่คุณถาม แต่ฉันคิดว่าฉันได้เตรียมคำถามติดตามไว้ล่วงหน้า :) (แน่นอนนี่จะหาลูกค้ารายแรกเท่านั้น... เพื่อค้นหาพวกเขาทั้งหมดเพียงแค่ใช้whereประโยคปกติ)


7
ฉันจะชี้ให้เห็นว่าคุณอาจรู้สึกซาบซึ้งที่ได้ทำสิ่งนี้ในภายหลังเมื่อมีการดีบั๊กหากคุณพบว่าตัวเองอยากรู้อยากเห็นว่าลูกค้ารายใดที่เหมาะสมกับเกณฑ์นั้น
mqp

1
เพียงแค่ชนคำตอบนี้ขึ้นหนึ่งเพราะฉันรักที่ชุมชน SO ก้าวไปอีกขั้นเพื่อเพิ่มคำถาม / คำตอบให้มากขึ้น
barneymc

1
ขอบคุณมันช่วยฉันได้ แต่บางครั้งฉันก็อยากได้boolผลลัพธ์ดังนั้นในกรณีนั้น.Anyหรือ.FindIndexใช้ที่นี่ เร็ว ไหม
shaijut

1
@stom: พวกเขาทั้งคู่ O (N) โดยทั่วไป ... พวกเขาเป็นเพียงการค้นหาเชิงเส้น
Jon Skeet

กระแทกสิ่งนี้ ฉันชอบวิธีที่คุณใช้ไวยากรณ์ของ listFirstOrDefault แทนที่จะทำ list.Where () FirstOrDefault
GunWanderer

25

ตัวเลือกหนึ่งสำหรับคำถามต่อไปนี้ (วิธีค้นหาลูกค้าที่อาจมีชื่อจำนวนเท่าใด):

List<string> names = new List<string>{ "John", "Max", "Pete" };
bool has = customers.Any(cus => names.Contains(cus.FirstName));

หรือเพื่อดึงลูกค้าจาก csv ของรายการที่คล้ายกัน

string input = "John,Max,Pete";
List<string> names = input.Split(',').ToList();
customer = customers.FirstOrDefault(cus => names.Contains(cus.FirstName));

10

ใช้ Linq คุณมีความเป็นไปได้มากมายโดยไม่ต้องใช้ lambdas:

//assuming list is a List<Customer> or something queryable...
var hasJohn = (from customer in list
         where customer.FirstName == "John"
         select customer).Any();

5
customerList.Any(x=>x.Firstname == "John")

สิ่งนี้ไม่ตอบคำถาม "ถ้า" มีรายการดังกล่าวอยู่ มันจะระบุค่าถ้ามีอยู่เท่านั้น จำเป็นต้องมีขั้นตอนเพิ่มเติมเพื่อพิจารณาว่าการแจงนับนี้เป็นแบบไม่ว่างเปล่าหรือไม่
jason

จากนั้นเปลี่ยนตำแหน่งเป็นใด ๆ อาจจะเป็นปรัชญามากขึ้นสำหรับฉัน ฉันแทบจะไม่ต้องรู้เลยว่าถ้าไม่สนใจพวกเขา @jmservera: คุณพูดถูก ฉันเลิกใช้ LINQ สักพักแล้วตอนนี้ใช้แลมบ์ดาโดยเฉพาะ
Chris Brandsma

ฉันไม่ได้พูดจาอวดดีเมื่อพูดว่าการใช้แลมบ์ดายังคงใช้เทคนิค LINQ อยู่ (โดยเฉพาะอย่างยิ่งคุณกำลังใช้ LINQ-to-Objects) คุณเพียงแค่ใช้วิธีการโทรมากกว่าคำหลักภาษา
ยูดาห์กาเบรียล Himango

คำตอบนี้แตกต่างจากของ zvolkov อย่างไร
dotnetN00b

4

เทคนิคที่ฉันใช้ก่อนค้นพบ.Any():

var hasJohn = (from customer in list
      where customer.FirstName == "John"
      select customer).FirstOrDefault() != null;

3
List<Customer> list = ...;
Customer john = list.SingleOrDefault(customer => customer.Firstname == "John");

john จะเป็นโมฆะหากไม่มีลูกค้าที่ใช้ชื่อ "John"


2
ซึ่งจะทำให้เกิดข้อยกเว้นหากมีลูกค้ามากกว่าหนึ่งรายชื่อจอห์น
Jon Skeet

1
ขอบคุณสำหรับความคิดเห็น ฉันจะทิ้งคำตอบไว้เป็นตัวอย่างที่ถูกต้องบางส่วน
M4N

มันยังคงใช้ได้ในสถานการณ์เมื่อคุณแน่ใจว่ามี 1 และคุณต้องการให้มีข้อยกเว้นหากมีมากกว่าหนึ่งดังนั้นฉันคิดว่ามันดีที่คุณไม่ได้ลบ
RichardOD

1

ความเป็นไปได้อีกอย่างหนึ่ง

if (list.Count(customer => customer.Firstname == "John") > 0) {
 //bla
}

4
มัน 'ดีกว่าที่จะใช้ใด ๆ ในสถานการณ์นี้
RichardOD

1

ลองนี้ฉันหวังว่าจะช่วยคุณ

 if (lstCustumers.Any(cus => cus.Firstname == "John"))
 {
     //TODO CODE
 }

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