リスト内の個別の値のリストを取得する


175

C#で、3つのStringメンバー変数を持つNoteというクラスがあるとします。

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

そして、私はタイプノートのリストを持っています:

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

著者列のすべての個別の値のリストを取得する最もクリーンな方法は何でしょうか?

リストを反復処理して、重複していないすべての値を別の文字列リストに追加することもできますが、これはダーティで非効率的です。これを1行で実行する魔法のLinq構造があるように感じますが、何も思いつきませんでした。

回答:


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

これIEnumerable<string>により、Author値のシーケンス()が返されます(一意の値ごとに1つ)。


1
Notes.Select(x => x.Author).AsParallel()。Distinct(); 「AsParallel()」を使用すると、順序を気にせず、リストにさらに多くの項目がある場合、パフォーマンスが向上する可能性があります。
サイ

1
@Kiquenet、Default平等比較器を考慮して明確。msdn.microsoft.com/en-us/library/bb348436(v=vs.110).aspx
Georg Patscheider

.Distinct()の前にToList()を追加する必要がありますか?
ファンĐứcBình2017年

1
Distinct()の前ではなく、リストに変換しようとしている場合。例:Notes.Select(x => x.Author).Distinct()。ToList();
MTwiford 2017

87

著者によるノートクラスの区別

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

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

1
単一のノートだけを保持するのでNotes、それNotes.GroupBy()は複数形のsようにNoteなるはずではありませんか?
kkuilla

30

Jon Skeetは、演算子を持つmorelinqと呼ばれるライブラリを作成しましたDistinctBy()。実装についてはこちらをご覧ください。あなたのコードは次のようになります

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

更新: 質問をもう一度読んだ後、明確な著者のセットを探しているだけであれば、カークは正しい答えを持っています。

追加されたサンプル、DistinctByのいくつかのフィールド:

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

優れたありがとう。Distinctメソッドを呼び出す前にリストを注文しても、正しい順序が維持されるのが気に入っています。
Vilhelm、2017年

リンクを更新しました。MoreLINQはGithubの上で今あるとNuget経由でインストールすることができますInstall-Package morelinq
チャド・レヴィ

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();

上記のロジックを使用して、一意Courseのを取得できます。


ToListの前のDistinctは私の時間を節約します。私はToListの後にやっていて、リストをIenumerableに変換できないエラーを出します。
Ajay2707

この演算子では、すべてのオブジェクトがオブジェクトのハッシュコードに基づいて一意であるため、Distinctはここでは機能しません。これに似たものが必要です-github.com/morelinq/MoreLINQ/blob/master/MoreLinq/DistinctBy.cs
Bose_geek

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

正確にはmciとは何ですか?単なる例の表ですか?答えはそのままでは少し厄介です。
Brad Koch

1
ええ、私はこれが私の元の質問が探していたものとは思わない(それが1年半前であり、プロジェクトが終了してから長い間であることを気にしないでください)。私が知ることができることから、これは重複を含む可能性のあるAuthor文字列のリストがすでにある場合に機能しますが、フィールドの1つとしてAuthor文字列を持つオブジェクトのリストからそのようなリストを抽出するために使用できませんでした。
Darrel Hoffman
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.