Dapatkan daftar nilai berbeda di Daftar


175

Dalam C #, katakanlah saya memiliki kelas yang disebut Catatan dengan tiga variabel anggota String.

public class Note
{
    public string Title;
    public string Author;
    public string Text;
}

Dan saya memiliki daftar tipe Catatan:

List<Note> Notes = new List<Note>();

Apa cara paling bersih untuk mendapatkan daftar semua nilai berbeda di kolom Penulis?

Saya bisa mengulangi daftar dan menambahkan semua nilai yang tidak duplikat ke daftar string lain, tetapi ini tampak kotor dan tidak efisien. Saya punya perasaan ada beberapa konstruksi Linq ajaib yang akan melakukan ini dalam satu baris, tetapi saya belum dapat menemukan apa pun.

Jawaban:


332
Notes.Select(x => x.Author).Distinct();

Ini akan mengembalikan urutan ( IEnumerable<string>) Authornilai - satu per nilai unik.


1
Notes. Pilih (x => x.Author) .AsParallel (). Distinct (); "AsParallel ()" mungkin memberikan beberapa manfaat kinerja, jika kami tidak peduli tentang pesanan dan memiliki lebih banyak item dalam daftar.
Sai

1
@Kiquenet, berbeda mengingat pembanding Defaultkesetaraan. msdn.microsoft.com/en-us/library/bb348436(v=vs.110).aspx
Georg Patscheider

Apakah kita perlu menambahkan ToList () sebelum .Distinct ()?
Phan Đức Bình

1
Tidak sebelum Perbedaan () tetapi setelah, jika Anda mencoba untuk mengkonversi ke daftar. Contoh: Notes. Pilih (x => x.Author) .Distinct (). Daftar ();
MTwiford

87

Bedakan kelas Note oleh Penulis

var DistinctItems = Note.GroupBy(x => x.Author).Select(y => y.First());

foreach(var item in DistinctItems)
{
    //Add to other List
}

1
Bukankah seharusnya Notesseperti Notes.GroupBy()jamak skarena Notehanya akan memegang satu Catatan tunggal?
kkuilla

30

Jon Skeet telah menulis perpustakaan bernama morelinq yang memiliki DistinctBy()operator. Lihat di sini untuk implementasinya. Kode Anda akan terlihat seperti

IEnumerable<Note> distinctNotes = Notes.DistinctBy(note => note.Author);

Pembaruan: Setelah membaca kembali pertanyaan Anda, Kirk memiliki jawaban yang benar jika Anda hanya mencari satu set Penulis yang berbeda.

Menambahkan sampel, beberapa bidang di DistinctBy:

res = res.DistinctBy(i => i.Name).DistinctBy(i => i.ProductId).ToList();

Luar biasa terima kasih. Saya suka itu menjaga urutan yang benar jika saya memesan daftar sebelum saya memanggil metode Berbeda.
Vilhelm

Saya memperbarui tautan. MoreLINQ sekarang ada di Github dan dapat diinstal melalui Nuget:Install-Package morelinq
Chad Levy

2
public class KeyNote
{
    public long KeyNoteId { get; set; }
    public long CourseId { get; set; }
    public string CourseName { get; set; }
    public string Note { get; set; }
    public DateTime CreatedDate { get; set; }
}

public List<KeyNote> KeyNotes { get; set; }
public List<RefCourse> GetCourses { get; set; }    

List<RefCourse> courses = KeyNotes.Select(x => new RefCourse { CourseId = x.CourseId, Name = x.CourseName }).Distinct().ToList();

Dengan menggunakan logika di atas, kita bisa mendapatkan unik Course.


Perbedaan Anda sebelum ToList menghemat waktu saya .. Saya lakukan setelah ToList dan memberikan kesalahan yang tidak dapat mengkonversi daftar ke Ienumerable.
Ajay2707

Perbedaan tidak akan bekerja di sini karena untuk operator ini setiap objek unik berdasarkan kode hash objek. Anda memerlukan beberapa yang serupa dengan ini - github.com/morelinq/MoreLINQ/blob/master/MoreLinq/DistinctBy.cs
Bose_geek

-2
mcilist = (from mci in mcilist select mci).Distinct().ToList();

Apa sebenarnya mci? Hanya tabel contoh? Jawabannya agak canggung.
Brad Koch

1
Ya, saya tidak berpikir ini melakukan apa yang dicari oleh pertanyaan awal saya (apalagi satu setengah tahun yang lalu dan proyek sudah lama selesai). Dari apa yang bisa saya katakan, ini akan berhasil jika saya sudah memiliki daftar string Penulis yang mungkin berisi duplikat, tetapi tidak dapat digunakan untuk mengekstrak daftar tersebut dari daftar objek yang memiliki string Penulis sebagai salah satu bidangnya.
Darrel Hoffman
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.