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”开头的单词。我要创建的列表是:

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" 有大写 Os,并且在使用 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

三个问题:

  • 您需要将结果分配给某些东西,否则它会被简单地丢弃。
  • 你需要使用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 回答