4

のコレクションがあるとしましょうHuman:

public class Human
{
    public string FirstName { get; set; }
    public string SecondName { get; set; }
    public string CompanyName { get; set; }
}

var people = new List<Human>(){...};

FirstName人を最初に次に、次にSecondNameで並べ替えながら、オートコンプリートを実装するにはどうすればよいCompanyNameでしょうか?

私は試した:

people.Where(x => x.FirstName.StartsWith(term) || x.SecondName.StartsWith(term) 
  ||  x.CompanyName.StartsWith(term))
  .OrderBy(x => x.FirstName).ThenBy(x => x.SecondName).ThenBy(x => x.CompanyName)

しかし、それは正しく機能しません。FirstName最初に一致したすべてのフィールドのみを表示し、次にフィールドのみを表示したいSecondNameなどです。

4

3 に答える 3

4
people.Where(x => x.FirstName.StartsWith(term)).OrderBy(x => x.FirstName)
.Concat(people.Where(x => x.SecondName.StartsWith(term)).OrderBy(x => x.SecondName))
.Concat(people.Where(x => x.CompanyName.StartsWith(term)).OrderBy(x => x.CompanyName))

.Distinct()1人が複数の方法で一致するケースを除外するかどうかに応じて、最後に追加します(このような場合、ソースに依存する.Union()代わりに使用することもでき.Concat()ます-列挙可能なソースで順序を維持するものとして文書化されていますが、他のクエリ可能なソースを使用するため、のソースによっては順序が乱れる可能性がありますpeople)。

于 2012-08-24T11:16:51.390 に答える
2

欲しくなると思います

people.Where(x => x.FirstName.StartsWith(term) ||
                  x.SecondName.StartsWith(term) ||
                  x.CompanyName.StartsWith(term))
    .OrderByDescending(x => x.FirstName.StartsWith(term))
    .ThenByDescending(x => x.SecondName.StartsWith(term))
    .ThenBy(x => x.FirstName)
    .ThenBy(x => x.SecondName)
    .ThenBy(x => x.CompanyName)

これは

  • 名前が最初に一致する全員
  • 次に、2 番目の名前が一致する全員
  • (すると、社名が一致する人が全員いる)
  • この順序内で、以前と同様に、名/姓/会社名で並べ替えられます。

yes/no の並べ替えは、 未満である必要Descendingfalseありtrueます。

Selectperson と 3 つの bool を使用して匿名クラスを ing することで、FirstNameMatchesこれをわずかに最適化できますSecondNameMatches。次に、これらの bool をWhereand の順序句で使用して、3 回ではなく 5 回の呼び出しを回避StartsWithできますが、基本的なソート作業。

2 番目の名前の一致を 2 番目の名前で並べ替え、会社名の一致を会社名で並べ替えたい場合は、より複雑になります。

于 2012-08-24T11:13:03.650 に答える
2

あなたがしている間違いは、ThenBy()afterを使用することですOrderBy()。これを使用すると、プロパティが一致するかどうかで並べ替えずに、既に並べ替えられたリストを内部的に並べ替えます。

すべきことは、リストを 3 つの方法でフィルタリングしてから、それらを結合し、 を使用して重複を削除することUnion()です。

それではどうですか:

people.Where( x => x.FirstName.StartsWith( term ) ).OrderBy( x => x.FirstName )
      .Union( people.Where( x => x.SecondName.StartsWith( term ) ).OrderBy( x => x.SecondName ) )
      .Union( people.Where( x => x.CompanyName.StartsWith( term ) ).OrderBy( x => x.CompanyName ) );

編集 :

Jon Hannaが指摘しQueryable.Union()たように、クエリの順序が保持されないため、使用すると機能しません。

Enumerable.Union() は順序を維持するように指定されていますが、Queryable.Union() は指定されていません。特定の実装は可能ですが、そうする必要はなく、別の (または同じものへの更新) はそうでない可能性があります。したがって、 people がメモリ内ソースでない場合、指定されたコードは任意の順序で結果を返すことができます。ジョン・ハンナ

于 2012-08-24T11:33:52.947 に答える