通过在开头放置以特定字母开头的单词来对字符串列表进行排序

时间:2012-05-08 14:16:40

标签: c# linq list

假设我有以下列表:

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

8 个答案:

答案 0 :(得分: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

This previous answer显示正确的方式进行不区分大小写的比较(即,不要使用上面的示例,不好)

答案 1 :(得分:2)

你的第一个错误是不是以不区分大小写的方式比较字符串;使用Contains(“ou”)时,“Out”和“Ounce”具有大写Os并且不会返回“true”。解决方法是在检查字母时使用ToLower()。

list.Where(x => x.ToLower().Contains("ou"))
    .OrderByDescending(x => x.ToLower.StartsWith("ou")) //true is greater than false.
    .Select(x => x);

答案 2 :(得分:1)

三个问题:

  • 您需要将结果分配给某些内容,否则就会将其丢弃。
  • 您需要使用OrderByDescending,因为如果您使用truefalse会在 OrderBy之后对进行排序。
  • 您需要使用不区分大小写的比较。

试试这个:

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;

答案 3 :(得分: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")));

答案 4 :(得分:0)

这将在以“OU”开头的单词的开头附加一个空格。

var result = list.Where(x => x.ToLowerInvariant().Contains("ou"))
                 .OrderBy(x => x.ToLowerInvariant()
                                .StartsWith("ou") ? " " + x : x.Trim());

答案 5 :(得分: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();

答案 6 :(得分: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);  
    }  
}

答案 7 :(得分: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));