Nhận danh sách các giá trị khác biệt trong Danh sách


175

Trong C #, giả sử tôi có một lớp có tên là Note với ba biến thành viên String.

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

Và tôi có một danh sách các loại Lưu ý:

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

Điều gì sẽ là cách sạch nhất để có được một danh sách tất cả các giá trị riêng biệt trong cột Tác giả?

Tôi có thể lặp qua danh sách và thêm tất cả các giá trị không trùng lặp vào danh sách chuỗi khác, nhưng điều này có vẻ bẩn và không hiệu quả. Tôi có cảm giác có một công trình Linq kỳ diệu sẽ làm điều này trong một dòng, nhưng tôi không thể nghĩ ra bất cứ điều gì.

Câu trả lời:


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

Điều này sẽ trả về một chuỗi ( IEnumerable<string>) các Authorgiá trị - một giá trị trên mỗi giá trị duy nhất.


1
Ghi chú.Select (x => x.Author) .AsParallel (). Distinc (); "AsParallel ()" có thể mang lại một số lợi ích về hiệu suất, nếu chúng tôi không quan tâm đến đơn hàng và có nhiều mặt hàng hơn trong danh sách.
Sai

1
@Kiquenet, khác biệt khi xem xét so sánh Defaultbình đẳng. msdn.microsoft.com/en-us/l
Library / bb348436 (v = vs.110) .aspx

Chúng ta có cần thêm ToList () trước .Distinc () không?
Phan Đức Bình

1
Không phải trước Phân biệt () mà sau, nếu bạn đang cố gắng chuyển đổi thành một danh sách. Ví dụ: Ghi chú.Select (x => x.Author) .Distinc (). ToList ();
MTwiford

87

Phân biệt lớp Ghi chú của Tác giả

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

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

1
Không phải nó được coi Noteslà ở Notes.GroupBy()dạng số nhiều sNotesẽ chỉ giữ một Lưu ý duy nhất sao?
kkuilla

30

Jon Skeet đã viết một thư viện gọi là morelinq có một DistinctBy()nhà điều hành. Xem ở đây để thực hiện. Mã của bạn sẽ trông như thế nào

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

Cập nhật: Sau khi đọc lại câu hỏi của bạn, Kirk có câu trả lời chính xác nếu bạn chỉ tìm kiếm một bộ Tác giả riêng biệt.

Đã thêm mẫu, một số trường trong DistincBy:

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

Tuyệt vời cảm ơn bạn. Tôi thích rằng nó giữ đúng thứ tự nếu tôi sắp xếp danh sách trước khi tôi gọi phương thức Phân biệt.
Vilmus

Tôi đã cập nhật các liên kết. MoreLINEQ hiện đã có trên Github và có thể được cài đặt qua 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();

Bằng cách sử dụng logic trên, chúng ta có thể có được Courses duy nhất .


Sự khác biệt của bạn trước khi ToList tiết kiệm thời gian của tôi .. Tôi đang thực hiện sau ToList và đưa ra lỗi không thể chuyển đổi danh sách thành Ienumerable.
Ajay2707

Khác biệt sẽ không hoạt động ở đây vì đối với toán tử này, mọi đối tượng là duy nhất dựa trên mã băm của đối tượng. Bạn cần một số tương tự như thế này - github.com/morelinq/MoreLINEQ/blob/master/MoreLinq/DistotypeBy.cs
Bose_geek

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

Chính xác thì mci là gì? Chỉ là một bảng ví dụ? Câu trả lời là một chút lúng túng.
Brad Koch

1
Vâng, tôi không nghĩ rằng đây là điều mà câu hỏi ban đầu của tôi đang tìm kiếm (đừng bận tâm đó là một năm rưỡi trước và dự án đã kết thúc từ lâu). Từ những gì tôi có thể nói, điều này sẽ hoạt động nếu tôi đã có một danh sách các chuỗi Author có thể chứa các bản sao, nhưng không thể được sử dụng để trích xuất một danh sách đó từ danh sách các đối tượng có chuỗi Author là một trong các trường của chúng.
Darrel Hoffman
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.