使用实体框架的复杂排序顺序

时间:2014-04-03 09:21:54

标签: regex oracle linq entity-framework

请帮助我如何排序此类列表。任何帮助将不胜感激。

我有一个字符串列表

List<string> lst = new List<string>();

lst.Add("2.1");

lst.Add("2.10A");

lst.Add("2.1B");

lst.Add("2.2");

lst.Add("ABC");

lst.Add("ABC1");

lst.Add("1.0");

排序顺序为:

    如果字符串以十进制开头,则
  • 十进制数字将视为整数。
  • 数字首先跟着字母

示例结果:

1.0,2.1,2.1B,2.2,2.10A,ABC,ABC1

P.S。如果可能,我可以使用Oracle订购它,实体框架将是一个更好的解决方案。

1 个答案:

答案 0 :(得分:2)

这个怎么样?在传递比较函数的列表上使用sort()方法。然后在比较函数中使用正则表达式提取删除'。'的初始十进制值。为了比较。将数字与字符串进行比较时,数字会更少。首先比较数字,如果相等,则比较剩余的字符串组件。

regexMatchDecimal的解释:

  • ?:非捕获组。
  • \d+匹配一个或多个数字。
  • [.]匹配文字.

GetString中的正则表达式只会在小数点后提取剩余的字符串组件(如果有)并将结果放在第一组()中。

[...]删除原始代码,因为它不再相关。

<强>更新

根据评论,首先将整数部分,然后整数和小数部分作为整数进行比较。

新版本:

static public class Program
{        
    static string regexMatchDecimal = @"(?:^\d+$)|^(?:\d+[.]\d+)";
    static string GetString( string input )
    {
        string result = "";
        Match match = Regex.Match( input, regexMatchDecimal + @"(.+)" );
        if( match.Success && match.Groups.Count > 1 )
        {
            result = match.Groups[1].Value;
        }
        return result;
    }
    static bool GetIntValue(string input, out int result)
    {
        result = 0;
        bool isConverted = false;
        Match match = Regex.Match( input, regexMatchDecimal );
        if( match.Success )
        {
            int pos = match.Value.IndexOf( '.' );
            string resultStr = "";
            if( pos != -1 )
            {
                resultStr = match.Value.Substring( 0, pos );
            }
            else
            {
                resultStr = match.Value;
            }
            isConverted = int.TryParse( resultStr, out result );
        }
        return isConverted;
    }
    static bool GetDecimalWholeValue( string input, out int result )
    {
        result = 0;
        bool isConverted = false;
        Match match = Regex.Match( input, regexMatchDecimal );
        if( match.Success )
        {
            string resultStr = match.Value.Replace( ".", "" );
            isConverted = int.TryParse( resultStr, out result );
        }
        return isConverted;
    }
    static public int Compare( string x, string y )
    {
        int xRes = 0;
        int yRes = 0;
        bool hasXNumber = GetIntValue( x, out xRes );
        bool hasYNumber = GetIntValue( y, out yRes );
        int result = 0;
        if( hasXNumber && hasYNumber )
        {
            result = xRes.CompareTo( yRes );
            if( result == 0 )//if same compare whole number decimal components
            {
                hasXNumber = GetDecimalWholeValue( x, out xRes );
                hasYNumber = GetDecimalWholeValue( y, out yRes );
                result = xRes.CompareTo( yRes );
                if( result == 0 ) //compare as string
                {
                    string xSubStr = GetString( x );
                    string ySubStr = GetString( y );
                    result = xSubStr.CompareTo( ySubStr );
                }
            }
        }
        else if( hasXNumber && !hasYNumber )
        {
            result = - 1;
        }
        else if( !hasXNumber && hasYNumber )
        {
            result = 1;
        }
        else
        {
            result = x.CompareTo( y );
        }
        return result;
    }        

    static void Go(List<string> lst)
    {
        lst.Add( "2.1" );
        lst.Add( "2.10A" );
        lst.Add( "2.1B" );
        lst.Add( "D.3" );
        lst.Add( "2.2" );
        lst.Add( "2.1A" );
        lst.Add( "ABC" );
        lst.Add( "2" );
        lst.Add( "ABC1" );
        lst.Add( "0.399C" );
        lst.Add( "1.0" );
        lst.Add( "3" );                        
        lst.Sort( Compare );
        foreach( var val in lst )
        {
            Console.WriteLine(val);
        }
    }

    static void Main( string[] args )
    {                              
        List<string> lst = new List<string>();
        Go(lst);
    }
}

现在输出:

0.399C
1.0
2
2.1
2.1A
2.1B
2.2
2.10A
3
ABC
ABC1
D.3
相关问题