ChatGPT解决这个技术问题 Extra ChatGPT

Get a list of distinct values in List

In C#, say I have a class called Note with three string member variables.

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

And I have a list of type Note:

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

What would be the cleanest way to get a list of all distinct values in the Author column?

I could iterate through the list and add all values that aren't duplicates to another list of strings, but this seems dirty and inefficient. I have a feeling there's some magical Linq construction that'll do this in one line, but I haven't been able to come up with anything.


K
Kirk Woll
Notes.Select(x => x.Author).Distinct();

This will return a sequence (IEnumerable<string>) of Author values -- one per unique value.


Notes.Select(x => x.Author).AsParallel().Distinct(); "AsParallel()" might give some performance benefit, if we doesn't care about order and have more items in the list.
@Kiquenet, distinct considering the Default equality comparer. msdn.microsoft.com/en-us/library/bb348436(v=vs.110).aspx
Do we need to add ToList() before .Distinct() ?
Not before the Distinct() but after, if you are trying to convert to a list. Ex: Notes.Select(x => x.Author).Distinct().ToList();
@Kirk does the IEnumerable of string still called "Author" or it has changed to anonymous? how to name a column after one has applied distinct to it? thanks
M
Mohammad Atiour Islam

Distinct the Note class by Author

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

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

Isn't it supposed to be Notes as in Notes.GroupBy() with a plural s as Note will only hold one single Note?
C
Chad Levy

Jon Skeet has written a library called morelinq which has a DistinctBy() operator. See here for the implementation. Your code would look like

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

Update: After re-reading your question, Kirk has the correct answer if you're just looking for a distinct set of Authors.

Added sample, several fields in DistinctBy:

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

Excellent, thank you. I love that it keeps the correct order if I order the list before I call the Distinct method.
I updated the links. MoreLINQ is now on Github and can be installed via Nuget: Install-Package morelinq
L
Lauren Rutledge
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();

By using the above logic, we can get the unique Courses.


your Distinct before ToList save my time.. I am doing after ToList and gives the error that cannot convert list to Ienumerable.
Distinct won't work here because for this operator every object is unique based on the hashcode of the object. You need some similar to this - github.com/morelinq/MoreLINQ/blob/master/MoreLinq/DistinctBy.cs
B
Brad Koch
mcilist = (from mci in mcilist select mci).Distinct().ToList();

What exactly is mci? Just an example table? The answer is a bit awkward as is.
Yeah, I don't think this does what my original question was looking for (never mind it was a year and a half ago and the project is long since finished). From what I can tell, this would work if I already had a list of Author strings which might contain duplicates, but could not be used to extract such a list from a list of objects which have the Author string as one of their fields.