繁体   English   中英

我如何排序列表 <string> 根据每个索引中每个字符串中的数字?

[英]How can i sort a List<string> according to the numbers in each string in each index?

最后在threadList中,例如在索引0中,我有:

1. hello world

然后在索引2中,我有:

33. hello

然后在索引3中,我有:

76. hi

在索引4中:

2. good

数字1 33 76 2是每个索引中字符串的一部分。

1. hello world是一个字符串。 我想根据数字对列表进行排序,因此在此示例中,它应该是:

1. hello world
2. good
33. hello
76. hi

同样,数字是它们不是int的字符串的一部分。

这是创建列表的方法:

public string GetResponsers(string contents)
        {
            string responser = "";
            List<string> threadList = new List<string>();
            int f = 0;
            int startPos = 0;
            while (true)
            {
                string firstTag = "<FONT CLASS='text16b'>";
                string lastTag = "&n";
                f = contents.IndexOf(firstTag, startPos);
                if (f == -1)
                {
                    break;
                }
                int g = contents.IndexOf(lastTag, f);
                startPos = g + lastTag.Length;
                responser = contents.Substring(f + 22, g - f - 22);

                threadList.Add(responser);
            }
            return responser;
        }

我想我明白了你想要的...

yourList.OrderBy(str => {
    var match = Regex.Match(str, @"^([-+]?\d+)");
    return match.Success ? int.Parse(match.Groups[1].Value) : int.MaxValue;
});

这将返回IEnumerable<string> ,该IEnumerable<string>由出现在字符串开头的整数的值排序。 没有数字的条目将放在末尾。


编辑:如果您想要对变量yourList进行排序,则必须重新分配它:

yourList = yourList
    .OrderBy(str => {
        var match = Regex.Match(str, @"^([-+]?\d+)");
        return match.Success ? int.Parse(match.Groups[1].Value) : int.MaxValue;
    })
    .ToList();

如果和我再说一次,如果我要呈现给您的列表中的示例与您使用的格式相同,那么您只需应用将自动排序的sort方法:

            List<string> lst = new List<string>()
            {
                "1. hello world",
                "76. hi",
                "33. hello",
                "2. good"
            };

            lst.Sort();//this will sort the list

此后,列表将具有您想要的输出。

编辑:正如所指出的(的确非常正确),我忘了那些有19个例子的情况,在这种情况下应用了带有比较的排序:

     lst.Sort((s1, s2) =>
     {
          string first = new string(s1.TakeWhile(c => char.IsDigit(c)).ToArray());
          string second = new string(s2.TakeWhile(c => char.IsDigit(c)).ToArray());
          return int.Parse(first).CompareTo(int.Parse(second));
     });

我认为您也可以尝试以下方法:

yourList.OrderBy(s => {
    int num;
    var parts = string.Split(s, '.');
    if (parts.Count > 0 && int.TryParse(parts[0], out num))
        return num;

    return int.MaxValue;
});

这样,您无需使用正则表达式即可确保对字符串的数字部分进行数字排序。

如果您使用的是Windows 7或更高版本,则它具有CompareStringEx函数,您可以P / Invoke进入。 它的SORT_DIGITSASNUMBERS选项完全SORT_DIGITSASNUMBERS您的需求:

    static int CompareCSEx(string x, string y)
    {
        return CompareStringEx("", SORT_DIGITSASNUMBERS, x, x.Length,
                               y, y.Length, null, null, IntPtr.Zero) - 2;
    }

    [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    static extern int CompareStringEx(String strLocale, uint flags,
                                      String str1, int count1, string str2,
                                      int count2, string version,
                                      string reserved, IntPtr param);

    const int SORT_DIGITSASNUMBERS = 8;

请注意,这会将字符串中的所有数字视为数字,而不仅仅是字符串开头的数字。

现在,愚蠢的基准测试表明它的运行速度比fourpastmidnight的解决方案快近4倍:

static void Main(string[] args)
{
    Random r = new Random(0);

    string[] values = (from i in Enumerable.Range(1, 500)
                        let order = r.Next()
                        orderby order
                        select i.ToString(CultureInfo.InvariantCulture)
                                    + ". " + RandomString(r)).ToArray();

    string[] fpmValues = values.ToArray();
    string[] csexValues = values.ToArray();

    Benchmark("FPM ", () => Array.Sort(fpmValues,
        new Comparison<string>(CompareFpm)));

    Benchmark("CSEX", () => Array.Sort(csexValues,
        new Comparison<string>(CompareCSEx)));

    Console.WriteLine("Sort equal: {0}",
        Enumerable.SequenceEqual(fpmValues, csexValues));
}

static string RandomString(Random r)
{
    int len = r.Next(1, 32);
    char[] buf = new char[len];

    for (int i = 0; i < len; ++i)
    {
        buf[i] = (char)r.Next('A', 'Z');
    }

    return new string(buf);
}

static int CompareFpm(string x, string y)
{
    int xi, yi;

    var parts = x.Split('.');
    if(parts.Length == 0 || !int.TryParse(parts[0], out xi))
    {
        xi = int.MaxValue;
    }

    parts = y.Split('.');
    if (parts.Length == 0 || !int.TryParse(parts[0], out yi))
    {
        yi = int.MaxValue;
    }

    return xi - yi;
}

static void Benchmark(string name, Action a)
{
    long start = Stopwatch.GetTimestamp(), end;
    long runs = 0;

    do
    {
        a();
        ++runs;
        end = Stopwatch.GetTimestamp();
    }
    while ((end - start) < (Stopwatch.Frequency * 5));

    Console.WriteLine("{0}: {1} runs/sec", name, runs / 5);
}

输出:

FPM : 681 runs/sec
CSEX: 2577 runs/sec
Sort equal: True

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM