1

私はLINQが苦手だと告白するのが好きです。データ付きのリストがあります。リストの最初の値を指定された値で検索し、データを最大出現回数で並べ替えます。これは、行の最大時間になります。

        List<SearchResult> list = new List<SearchResult>() { 
            new SearchResult(){ID=1,Title="Cat"},
            new SearchResult(){ID=2,Title="dog"},
            new SearchResult(){ID=3,Title="Tiger"},
            new SearchResult(){ID=4,Title="Cat"},
            new SearchResult(){ID=5,Title="cat"},
            new SearchResult(){ID=6,Title="dog"},
        };

「犬の猫」のようなデータでリストを検索して並べ替えると、出力は次のようになります。

ID=1,Title=Cat
ID=4,Title=Cat
ID=5,Title=Cat
ID=2,Title=dog
ID=6,Title=dog

このcatキーワードがすべての行で最大時間を見つけ、次にdogが最大時間を見つけたため、すべての猫が最初に来ます。

以下のデータは検索語に含まれていないため、表示されません

ID=3,Title=Tiger

解決策を探しています。ありがとう

ポーションコードの更新

        List<SearchResult> list = new List<SearchResult>() { 
            new SearchResult(){ID=1,Title="Geo Prism 1995 - ABS #16213899"},
            new SearchResult(){ID=2,Title="Excavator JCB - ECU P/N: 728/35700"},
            new SearchResult(){ID=3,Title="Geo Prism 1995 - ABS #16213899"},
            new SearchResult(){ID=4,Title="JCB Excavator - ECU P/N: 728/35700"},
            new SearchResult(){ID=5,Title="Geo Prism 1995 - ABS #16213899"},
            new SearchResult(){ID=6,Title="dog"},
        };

        var to_search = new[] { "Geo", "JCB" };
        var result = list.Where(sr => to_search.Any(ts => String.Compare(ts, sr.Title, StringComparison.OrdinalIgnoreCase) == 0))
                         .GroupBy(sr => sr.Title.ToLower())
                         .OrderByDescending(g => g.Count());

        var matched = result.SelectMany(m => m);

        var completeList = matched.Concat(list.Except(matched));

        dataGridView2.DataSource = completeList.ToList();

別のアプリでロジックを試しましたが、機能していません。ロジックによると、最初に3行にGEOキーワードがあり、次の2行にJCBがあり、次に比類のない残りがあります。urコードで変更する必要があるもの。助けてください。ありがとう

4

3 に答える 3

3

これにより、リストがフィルター処理され、 でグループ化されTitle、グループがサイズで並べ替えられます。

List<SearchResult> list = new List<SearchResult>() { 
    new SearchResult(){ID=1,Title="Cat"},
    new SearchResult(){ID=2,Title="dog"},
    new SearchResult(){ID=3,Title="Tiger"},
    new SearchResult(){ID=4,Title="Cat"},
    new SearchResult(){ID=5,Title="cat"},
    new SearchResult(){ID=6,Title="dog"},
};

var to_search = new[] { "cat", "dog" };

var result = list.Where(sr => to_search.Any(ts => String.Compare(ts, sr.Title, StringComparison.OrdinalIgnoreCase) == 0))
                 .GroupBy(sr => sr.Title.ToLower())
                 .OrderByDescending(g => g.Count());

foreach (var group in result)
    foreach (var element in group)
        Debug.WriteLine(String.Format("ID={0},Title={1}", element.ID, element.Title));

出力:

ID=1,Title=Cat
ID=4,Title=Cat
ID=5,Title=cat
ID=2,Title=dog
ID=6,Title=dog

実際のグループ化を気にしない場合は、SelectManyを使用してグループのリストをフラット化できます。

(このコードは の大文字と小文字を区別しないことに注意してくださいTitle。これがあなたが望むものなのか、それともコードのタイプミスなのかはわかりません: あなたは and を使用してcatおりCat、出力では のみCatですが、dog大文字ではありません。)

編集:

一致しないアイテムを取得するには、Exceptを使用できます。

var unmatched = list.Except(result.SelectMany(m => m)); // beware! contains the tiger!

編集2:

var result = list.Where(sr => to_search.Any(ts => String.Compare(ts, sr.Title, StringComparison.OrdinalIgnoreCase) == 0))
                 .GroupBy(sr => sr.Title.ToLower())
                 .OrderByDescending(g => g.Count());

var matched = result.SelectMany(m => m);

var completeList = matched.Concat(list.Except(matched));

foreach (var element in completeList)
    Debug.WriteLine(String.Format("ID={0},Title={1}", element.ID, element.Title));

出力

ID=1,Title=Cat
ID=4,Title=Cat
ID=5,Title=cat
ID=2,Title=dog
ID=6,Title=dog
ID=3,Title=Tiger

編集 3

var result = from searchResult in list
             let key_string = to_search.FirstOrDefault(ts => searchResult.Title.ToLower().Contains(ts.ToLower()))
             group searchResult by key_string into Group
             orderby Group.Count() descending
             select Group;
于 2012-07-09T13:18:41.567 に答える
1

私は、次のトリックを行う必要があると思います。

var searchText = "cat dog";
var searchResult = list
  .Select(i => new { 
       Item = i, 
       Count = list.Count(x => string.Compare(x.Title, i.Title, true) == 0)  // Add counter
  })
  .Where(i => searchText.Contains(i.Item.Title))
  .OrderByDescending(i => i.Count)
  .ThenBy(i => i.Item.ID)
  .ToList()

アップデート

最後に一致しないデータが必要な場合は、匿名オブジェクトに別の並べ替えプロパティを追加する必要があります。

var searchText = "cat dog";
var searchResult = list
  .Select(i => new { 
       Item = i, 
       Matched = searchText.Contains(i.Item.Title.ToUpper()),
       Count = list.Count(x => string.Compare(x.Title, i.Title, true) == 0)  // Add counter
  })
  .OrderByDescending(i => i.Matched)
  .ThenBy(i => i.Count)
  .ThenBy(i => i.Item.ID)
  .ToList()
于 2012-07-09T13:17:56.953 に答える
1
IEnumerable<string> pets = new[] { "Cat", "dog", "Tiger", "Cat", "cat", "dog" };
var test = pets
    .Where(p=>p.ToUpperInvariant() == "CAT" || p.ToUpperInvariant() == "DOG")
    .GroupBy(p => p.ToUpperInvariant())
    .OrderByDescending(g => g.Count())
    .SelectMany(p => p);

foreach (string pet in test)
    Console.WriteLine(pet);
于 2012-07-09T13:21:44.033 に答える