4

私が次のリストを持っていると仮定します:

IList<string> list = new List<string>();
list.Add("Mouse");
list.Add("Dinner");
list.Add("House");
list.Add("Out");
list.Add("Phone");
list.Add("Hat");
list.Add("Ounce");

LINQを使用して、「ou」を含む単語を選択し、「ou」で始まる単語が最初にリストされ、次に「ou」を含むが「ou」で始まらない単語がリストされるように選択を並べ替えるにはどうすればよいですか。私が作成しようとしているリストは次のようになります。

Ounce
Out
House
Mouse

私は次のことを思いついたが、それは機能していない:

list.Where(x => x.Contains("ou"))
    .OrderBy(x => x.StartsWith("ou"))
    .Select(x => x);
4

8 に答える 8

5

大文字と小文字を区別して比較します。また、が必要OrderByDescending()です。大文字と小文字を区別しないようにするための迅速で汚い方法は次のToLowerInvariant()とおりです。

var result = list.Where(x => x.ToLowerInvariant().Contains("ou"))
                    .OrderByDescending(x => x.ToLowerInvariant().StartsWith("ou"))
                    .Select(x => x);

実例: http: //rextester.com/GUR97180

この前の回答は、大文字と小文字を区別しない比較を行う正しい方法を示しています(つまり、上記の例を使用しないでください、悪いです)

于 2012-05-08T14:21:02.190 に答える
2

最初の間違いは、大文字と小文字を区別しない方法で文字列を比較することではありません。「Out」と「Ounce」には大文字のOがあり、Contains( "ou")を使用すると「true」は返されません。解決策は、文字をチェックするときにToLower()を使用することです。

list.Where(x => x.ToLower().Contains("ou"))
    .OrderByDescending(x => x.ToLower.StartsWith("ou")) //true is greater than false.
    .Select(x => x);
于 2012-05-08T14:22:01.420 に答える
1

3つの問題:

  • 結果を何かに割り当てる必要があります。そうしないと、単に破棄されます。
  • を使用するとソートOrderByDescendingれるため、を使用する必要があります。true falseOrderBy
  • 大文字と小文字を区別しない比較を使用する必要があります。

これを試して:

var needle = "ou";
var stringComparison = StringComparison.OrdinalIgnoreCase;

var query =
    from word in list
    let index = word.IndexOf(needle, stringComparison)
    where index != -1
    orderby index
    select word;
于 2012-05-08T14:19:50.187 に答える
0
list = list.Where(x => x.ToLower().Contains("ou"))
           .OrderBy(x => !x.ToLower().StartsWith("ou")).ToList();

または、Listのメソッドを使用する(IListからListに変更する):

list.RemoveAll(x => !x.ToLower().Contains("ou"));
list.Sort((s1, s2) => -1 * 1.ToLower().StartsWith("ou")
                            .CompareTo(s2.ToLower().StartsWith("ou")));
于 2012-05-08T14:21:16.103 に答える
0

これにより、「OU」で始まる単語の先頭に空のスペースが追加されます。

var result = list.Where(x => x.ToLowerInvariant().Contains("ou"))
                 .OrderBy(x => x.ToLowerInvariant()
                                .StartsWith("ou") ? " " + x : x.Trim());
于 2012-05-08T14:24:52.040 に答える
0

私はこれがあなたが探しているものだと思います:

list = list.Where(x => x.IndexOf("ou", StringComparison.OrdinalIgnoreCase) >= 0)
            .OrderByDescending(x => x.StartsWith("ou", StringComparison.OrdinalIgnoreCase))
            .ThenBy(x => x)
            .ToList();

ToLower文字列(または上位)を変換する代わりに、StringComparison列挙型(現在OrdinalIgnoreCase)を使用していることに注意してください。これにより、どの文化でも期待どおりに一貫して機能することが保証されます。状況に応じて、大文字と小文字を区別しない適切な比較を選択してください。

LINQクエリ構文を使用する場合は、次のようになります。

list = (from x in list
        where x.IndexOf("ou", StringComparison.OrdinalIgnoreCase) >= 0
        orderby x.StartsWith("ou", StringComparison.OrdinalIgnoreCase) descending, x
        select x).ToList();
于 2012-05-08T14:27:18.607 に答える
0

list.Sort次のようにカスタム比較子のインスタンスを渡すことで、メソッドを呼び出すことができます。

public class MyCustomStringComparer: IComparer<string>  
{  
    public int Compare(Entity x, Entity y)  
    {  
        int result = 0;

        if (x.ToLower().StartsWith("ou") && y.ToLower().StartsWith("ou"))  
            result = x.Compare(y);  
        else if (x.ToLower().StartsWith("ou") && !y.ToLower().StartsWith("ou"))  
            result = -1;  
        else if (!x.ToLower().StartsWith("ou") && y.ToLower().StartsWith("ou"))  
            result = 1;  
        else  
            result = x.Compare(y);  

        return (result);  
    }  
}
于 2012-05-08T14:33:36.243 に答える
0
var bla = "ou";

var list = new List<string>{
            "Mouse",
            "Dinner",
            "House",
            "Out",
            "Phone",
            "Hat",
            "Ounce"};


var groupa = list.GroupBy(x =>x.ToLower().Contains(bla));

groupa.First().ToList().OrderByDescending(x => x.ToLower().StartsWith(bla));
于 2012-05-08T14:33:41.263 に答える