4

我有一个需要排序的分隔字符串。首先我需要检查'Francais'是否在字符串中,如果是,它首先出现,然后'Anglais'是下一个,如果它存在。在那之后,其他一切都是按字母顺序排列的。谁能帮我?这是我到目前为止所拥有的,没有排序

private string SortFrench(string langs)
    {
       string _frenchLangs = String.Empty;
       string retval = String.Empty;

        _frenchLangs = string.Join(" ; ",langs.Split(';').Select(s => s.Trim()).ToArray());

        if (_frenchLangs.Contains("Francais"))
            retval += "Francais";

        if (_frenchLangs.Contains("Anglais"))
        {
            if (retval.Length > 0)
                retval += " ; ";

            retval += "Anglais";
        }

        //sort the rest

        return retval;
    }
4

9 回答 9

11

有人喜欢我的评论,所以想我会继续将其转换为您的代码:

private string SortFrench(string langs)
{
    var sorted          = langs.Split(';')
        .Select(s => s.Trim())
        .OrderByDescending( s => s == "Francais" )
        .ThenByDescending( s => s == "Anglais" )
        .ThenBy ( s => s )
        .ToArray();

    return string.Join(" ; ",sorted);
}

我的语法可能略有偏差,因为我已经在 Unix 世界中待了一段时间并且最近没有使用太多 LINQ,但希望它有所帮助。

于 2013-05-15T14:37:44.077 回答
6

您应该使用自定义比较器

它将允许您使用内置的集合排序功能,或使用您自己的标准的linq OrderBy

于 2013-05-15T14:09:11.517 回答
5

这就是我想出的。您可以在 Select 之后更改.Sort()for a OrderBy(lang => lang),但我发现这样更干净。

public string SortLanguages(string langs)
{
    List<string> languages = langs.Split(';').Select(s => s.Trim()).ToList();

    languages.Sort();
    PlaceAtFirstPositionIfExists(languages, "anglais");
    PlaceAtFirstPositionIfExists(languages, "francais");

    return string.Join(" ; ", languages);
}

private void PlaceAtFirstPositionIfExists(IList<string> languages, string language)
{
    if (languages.Contains(language))
    {
            languages.Remove(language);
            languages.Insert(0, language);
    }
}
于 2013-05-15T14:19:56.253 回答
3

尝试这个:

private string SortFrench(string langs)
{
    string _frenchLangs = String.Empty;

    List<string> languages = langs
        .Split(';')
        .Select(s => s.Trim())
        .OrderBy(s => s)
        .ToList();

    int insertAt = 0;

    if (languages.Contains("Francais"))
    {
        languages.Remove("Francais");
        languages.Insert(insertAt, "Francais");
        insertAt++;
    }

    if(languages.Contains("Anglais"))
    {
        languages.Remove("Anglais");
        languages.Insert(insertAt, "Anglais");
    }

    _frenchLangs = string.Join(" ; ", languages);

    return _frenchLangs;
}
于 2013-05-15T14:18:17.243 回答
2

一切都可以在一行中完成

private string SortFrench(string langs)
{
    return string.Join(" ; ", langs.Split(';').Select(s => s.Trim())
                    .OrderBy(x => x != "Francais")
                    .ThenBy(x => x != "Anglais")
                    .ThenBy(x=>x));
}
于 2013-05-15T14:35:36.520 回答
0

你也可以使用Array.Sort(yourStringArray)

于 2013-05-15T14:19:52.400 回答
0

此代码创建语言列表,使用自定义比较器对它们进行排序,然后将排序后的列表重新组合在一起:

        const string langs = "foo;bar;Anglais;Francais;barby;fooby";
        var langsList = langs.Split(';').ToList();
        langsList.Sort((s1, s2) =>
            {
                if (s1 == s2)
                    return 0;
                if (s1 == "Francais")
                    return -1;
                if (s2 == "Francais")
                    return 1;
                if (s1 == "Anglais")
                    return -1;
                if (s2 == "Anglais")
                    return 1;
                return s1.CompareTo(s2);
            });
        var sortedList = string.Join(";", langsList);
        Console.WriteLine(sortedList);
于 2013-05-15T14:54:17.007 回答
0

这样您就可以在前面设置任何单词列表:

private static string SortFrench(string langs, string[] setStartList)
{
    string _frenchLangs = String.Empty;
    List<string> list = langs.Split(';').Select(s => s.Trim()).ToList();
    list.Sort();
    foreach (var item in setStartList){
    if (list.Contains(item))
    {
        list.Remove(setFirst);
    }
   }
    List<string> tempList = List<string>();
    tempList.AddRange(setStartList);
    tempList.AddRange(list);
    list = tempList;
    _frenchLangs = string.Join(" ; ", list);

    return _frenchLangs;
}
于 2013-05-15T14:21:46.050 回答
0

按字母顺序排序很简单;.OrderBy(s => s)在此之前添加.ToArray()将做到这一点。基于关键字的存在进行排序比较棘手。

快速而肮脏的方法是分成三个:

  • 包含 "Francais" 的字符串:.Where(s => s.Contains("Francais")
  • 包含 "Anglais" 的字符串:.Where(s => s.Contains("Anglais")
  • 其余的部分:.Where(s => !francaisList.Contains(s) && !anglaisList.Contains(s))

然后,您可以按字母顺序对其中的每一个进行排序,并将它们连接起来。

或者,您可以IComparer使用您描述的逻辑来实现:

对于字符串 A 和 B:

  • 如果 A 包含“Francais”
    • 如果 B 包含“Francais”,按字母顺序排列
  • 别的
    • 如果 B 包含“Francais”,则 B 先行
    • 别的
      • 如果 A 包含“Anglais”
        • 如果 B 包含“Anglais”,则按字母顺序排列
        • 否则,A先行
      • 否则,按字母顺序

可能有逻辑重新安排的空间来简化这一点。将所有逻辑封装在一个实现的类中IComparer,您可以指定该类供其使用,.OrderBy()以使其根据您的自定义逻辑对查询结果进行排序。

于 2013-05-15T14:17:14.357 回答