Search code examples
c#asp.net-mvclinqvisual-studio-2010asp.net-mvc-views

How to implement sort of string by using c#.net(MVC)?


I'm practicing MVC View by myself, and I've been trying to sorting the data array by using fields Chapter (its a string type).

If I using orderby row.Chapter asccending, it will be

10.1
8.1
9.1

But I hope it will be

8.1
9.1
10.1

So I've been using orderby float.Parse(row.Chapter) descending to achieve the expected.

@{
    var originalRows = new[]{
        new{
            Title="Title1",
            Chapter="8.1",
            Description="NA"
        },
        new{
            Title="Title2",
            Chapter="9.1",
            Description="NA"
        },
        new{
            Title="Title3",
            Chapter="10.1",
            Description="NA"
        }
    };

    var rows =
        from row in originalRows
        orderby float.Parse(row.Chapter) descending
        select row;
}
<br />
<div>
    <table>
        <thead>
            <tr>
                <td colspan='2' style='font-weight:bold;text-align:left;'>
                    INFORMATION:
                </td>
            </tr>
        </thead>
        <tbody>
            for (var i = rows.Count(); i-->0;)
            {
                var row = rows.ElementAt(i);

                <tr>
                    <td colspan='2'>
                        <b>@(row.Title)<br /></b>
                        <b>@(row.Chapter)<br /></b>
                        <pre>@(row.Description)</pre>
                    </td>
                </tr>
            }
        </tbody>
        <tfoot>
            <tr height='0'>
                <td width='50%' style='border:none'></td>
                <td width='50%' style='border:none'></td>
            </tr>
        </tfoot>
    </table>
</div>

Is there any other way is more better to achieve?


Solution

  • What you have now is correct for this case. However I think you could reorganize the code to use custom comparer. In other words, what you have now would look like

    int CompareFloat(string a, string b)
    {
        return float.Parse(a).CompareTo(float.Parse(b));
    
    }
    
    var list = new[] { "1.5.47","4.5","5.6","6.6" };
    
    var comparer = Comparer<string>.Create(CompareFloat);
    
    var result = list.OrderBy(i => i, comparer).ToList();
    

    Why doing so? Because here you can improve comparison logic. E.g. float.Parse will fail on parsing 1.5.47, while with your custom comparer you could change it to something like

    int Compare(string a, string b)
    {
        var aV = a.Split('.');
        var bV = b.Split('.');
    
        if (aV.Length != bV.Length)
            return aV.Length.CompareTo(bV.Length);
    
        for(var i = 0; i < aV.Length; i++)
        {
            var comparisonResult = Int32.Parse(aV[i]).CompareTo(Int32.Parse(bV[i]));
    
            if (comparisonResult != 0)
                return comparisonResult;
        }
    
        return 0;
    
    }
    
    var list = new[] { "1.5.47","4.5","5.6","6.6" };
    
    var comparer = Comparer<string>.Create(Compare);
    
    var result = list.OrderBy(i => i, comparer).ToList();
    

    But in general what you do is correct - I don't see any advantage on e.g. using decimal instead of float - taking into account which numbers you expect to have as chapter numbers.