Mencari jika ada nilai dalam daftar objek menggunakan Linq

228

Katakanlah saya memiliki kelas Customeryang memiliki properti FirstName. Lalu aku punya List<Customer>.

Dapatkah LINQ digunakan untuk mengetahui apakah daftar tersebut memiliki pelanggan dengan Firstname = 'John'satu pernyataan .. bagaimana?

Tony_Henrich
sumber

Jawaban:

459

LINQ mendefinisikan metode ekstensi yang sempurna untuk menyelesaikan masalah ini:

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

pastikan Anda merujuk System.Core.dll, di situlah LINQ tinggal.

zvolkov
sumber
24
Adakah yang baik, saya ingin tahu berapa banyak pengembang yang menggunakan Hitung ketika mereka harus menggunakan?
RichardOD
12
Anda juga dapat melakukan pencarian case-sensitive: cus => cus.FirstName.Equals ("John", StringComparison.CurrentCultureIgnoreCase)
jmservera
1
Saya tahu ini adalah pertanyaan lama tetapi mengapa kita tidak menggunakan metode yang ada? Melihat seperti itu dibuat untuk melihat apakah ada sesuatu.
Blackunknown
6
Karena tidak semua koleksi memiliki Ada, dan itu tidak mengambil ekspresi lambda, melainkan objek yang kita cari sendiri.
zvolkov
1
@ zvolkov, Gagasan mengapa penyelamat saya menyarankan agar saya menggunakan bool has = list.All (cus => cus.FirstName! = "John"); Apakah ini lebih optimal?
Gullu
105

Jawaban zvolkov adalah jawaban yang tepat untuk mencari tahu apakah ada pelanggan seperti itu. Jika Anda perlu menggunakan pelanggan setelah itu, Anda dapat melakukan:

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

Saya tahu ini bukan yang Anda tanyakan, tetapi saya pikir saya akan menjawab pertanyaan lanjutan :) (Tentu saja, ini hanya menemukan pelanggan pertama ... untuk menemukan semuanya, gunakan saja whereklausa normal .)

Jon Skeet
sumber
7
Saya akan menunjukkan bahwa Anda mungkin menghargai telah melakukan ini nanti ketika datang untuk debugging, jika Anda tiba-tiba penasaran dengan pelanggan mana yang sesuai dengan kriteria.
mqp
1
Hanya menambah satu jawaban ini karena saya suka cara komunitas SO melakukan langkah ekstra untuk menambahkan lebih banyak lagi pada pertanyaan / jawaban.
barneymc
1
terima kasih itu membantu saya, tetapi kadang-kadang saya hanya ingin mendapatkan boolhasil, jadi dalam hal ini .Anyatau .FindIndexdigunakan di sini yang cepat ?
shaijut
1
@stom: Mereka berdua O (N), pada dasarnya ... mereka hanya pencarian linear.
Jon Skeet
menabrak ini. Saya suka cara Anda menggunakan sintaks list.FirstOrDefault alih-alih melakukan list.Where (). FirstOrDefault.
GunWanderer
25

Satu opsi untuk pertanyaan tindak lanjut (bagaimana menemukan pelanggan yang mungkin memiliki sejumlah nama depan):

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

atau untuk mengambil pelanggan dari csv dari daftar serupa

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

Menggunakan Linq Anda memiliki banyak kemungkinan, berikut ini tanpa menggunakan lambdas:

//assuming list is a List<Customer> or something queryable...
var hasJohn = (from customer in list
         where customer.FirstName == "John"
         select customer).Any();
jmservera
sumber
5
customerList.Any(x=>x.Firstname == "John")
Chris Brandsma
sumber
Ini tidak menjawab pertanyaan "jika" entri seperti itu ada; itu hanya menyebutkan nilai-nilai jika ada. Diperlukan langkah ekstra untuk menentukan apakah enumerasi ini tidak kosong.
jason
Kemudian ubah Where to Any. Mungkin lebih filosofis buat saya. Saya jarang perlu tahu jika tanpa peduli yang mana. @ jmservera: Anda benar. Saya menyerah LINQ beberapa waktu lalu dan sekarang menggunakan Lambda secara eksklusif.
Chris Brandsma
Saya tidak bermaksud terlalu berlebihan ketika saya mengatakan bahwa menggunakan panggilan lambda secara teknis masih menggunakan LINQ. (Khususnya, Anda menggunakan LINQ-to-Objects.) Anda hanya menggunakan metode panggilan daripada kata kunci bahasa.
Yehuda Gabriel Himango
Apa perbedaan jawaban ini dengan zvolkov?
dotnetN00b
4

Teknik yang saya gunakan sebelum menemukan .Any():

var hasJohn = (from customer in list
      where customer.FirstName == "John"
      select customer).FirstOrDefault() != null;
Ian Boyd
sumber
3
List<Customer> list = ...;
Customer john = list.SingleOrDefault(customer => customer.Firstname == "John");

john akan menjadi nol jika tidak ada pelanggan dengan nama depan "John".

M4N
sumber
2
Itu akan menimbulkan pengecualian jika lebih dari satu pelanggan disebut John.
Jon Skeet
1
Terima kasih atas komentarnya. Saya akan meninggalkan jawabannya sebagai contoh yang benar sebagian.
M4N
Itu masih berlaku dalam skenario ketika Anda yakin ada 1 dan Anda ingin pengecualian yang muncul jika lebih dari satu, jadi saya pikir itu baik bahwa Anda tidak menghapusnya.
RichardOD
1

Kemungkinan lain

if (list.Count(customer => customer.Firstname == "John") > 0) {
 //bla
}
Krassi
sumber
4
Lebih baik menggunakan Any dalam skenario ini.
RichardOD
1

Coba ini, saya harap ini membantu Anda.

 if (lstCustumers.Any(cus => cus.Firstname == "John"))
 {
     //TODO CODE
 }
Fabio Stratotti
sumber
4
Itu sama dengan jawaban yang diterima dari lebih dari 8 tahun yang lalu. Pastikan jawaban Anda unik di antara semua jawaban.
Tony_Henrich