c# - 像数字一样的顺序字符串

标签 c# linq

<分区>

我想对有时包含数值的字符串列表进行排序

我的列表是这样的:

  • 卧室 1
  • 卧室 2
  • 卧室 10
  • 浴室 1
  • 浴室 2
  • 浴室 10
  • 1 盏灯
  • 1 篇论文

如果我只使用 orderby: roomList.OrderBy(x => x.Name) 我得到这个列表:

  • 1 盏灯
  • 1 篇论文
  • 浴室 1
  • 浴室 10
  • 浴室 2
  • 卧室 1
  • 卧室 10
  • 卧室 2

是否可以像这样获取列表?

  • 1 盏灯
  • 1 篇论文
  • 浴室 1
  • 浴室 2
  • 浴室 10
  • 卧室 1
  • 卧室 2
  • 卧室 10

所有列表元素都不包含数字,列表长约 1500 行

我已经尝试使用这段代码,它在包含数字的元素上运行良好,但不适用于字符串元素:

public class SemiNumericComparer : IComparer<string>
    {
        public int Compare(string s1, string s2)
        {
            if (IsNumeric(s1) && IsNumeric(s2))
            {
                if (Convert.ToInt32(s1) > Convert.ToInt32(s2)) return 1;
                if (Convert.ToInt32(s1) < Convert.ToInt32(s2)) return -1;
                if (Convert.ToInt32(s1) == Convert.ToInt32(s2)) return 0;
            }

            if (IsNumeric(s1) && !IsNumeric(s2))
                return -1;

            if (!IsNumeric(s1) && IsNumeric(s2))
                return 1;

            return string.Compare(s1, s2, true);
        }

        public static bool IsNumeric(object value)
        {
            try
            {
                int i = Convert.ToInt32(value.ToString());
                return true;
            }
            catch (FormatException)
            {
                return false;
            }
        }
    }

最佳答案

尝试以下自定义 IComparable :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace ConsoleApplication107
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> input = new List<string>() { "1 Light", "1 Paper", "Bathroom 1", "Bathroom 2", "Bathroom 10", "Bedroom 1", "Bedroom 2", "Bedroom 10" };

            List<string> results = input.Select(x => new { s = x, order = new Order(x) }).OrderBy(x => x.order).Select(x => x.s).ToList();

        }
    }
    public class Order : IComparable<Order>
    {
        List<string> split { get; set; }

        public Order(string line)
        {
            split = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
        }

        public int CompareTo(Order other)
        {

            int min = Math.Min(split.Count, other.split.Count);
            int thisNumber = 0;
            int otherNumber = 0;
            for (int i = 0; i < min; i++)
            {
                if (split[i] != other.split[i])
                {
                    if ((int.TryParse(split[i], out thisNumber)))
                    {
                        if ((int.TryParse(other.split[i], out otherNumber)))
                        {
                            return thisNumber.CompareTo(otherNumber); //both numbers
                        }
                        else
                        {
                            return -1; // this is number other is string : this comes first
                        }
                    }
                    else
                    {
                        if ((int.TryParse(other.split[i], out otherNumber)))
                        {
                            return 1; //other is number this is string : other comes first
                        }
                        else
                        {
                            return split[i].CompareTo(other.split[i]);
                        }
                    }
                }
            }

            return split.Count.CompareTo(other.split.Count);

        }

    }
}

关于c# - 像数字一样的顺序字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55417936/

相关文章:

c# - LINQ复合选择问题

c# - 我想检查 IEnumerable 的计数,但效率很低

c# - 如何修改linq查询?

c# - 如何使用 Silverlight 实现 WCF,同时支持 ASP.NET session 状态和 SSL?

c# - Asp.net grdiview : can i format the dataitems in an itemtemplate?

c# - 没有主体的虚拟方法

c# - 为什么 float.MaxValue 0xFF 0xFF 0x7F 0x7F 而不是 0x7F, 0xFF, 0xFF, 0xFF 之类的整数?

c# - Entity Framework Core 2(代码优先)更新值不起作用

c# - 如果子节点元素相等,如何添加父节点?

c# - 使用其标签属性删除 ListViewItem 且不使用 foreach 循环