2

I have a list of items and i am using the below code to sort this list of items

List<ModelItems> sorted_items = originalItems.OrderBy(i => i.Page).ToList();

where Page is a property that can be either an integer number or a string , so i set it as of type String and is not a required property in the model also. So it can be empty as well.

But while sorting , since its a string now it gives items in this order for example 1,17,3,37,5,"","s" etc

Can we sort the List using Linq in an integer way ?

Like the result should be numbers first, then strings like 1,3,5,17,37,"b","g","",.....

Shaharyar
  • 12,254
  • 4
  • 46
  • 66
Sebastian
  • 4,625
  • 17
  • 76
  • 145
  • Did you consider to implement IComparable in ModelItems-Class? Then just coll originalItems.OrderBy(). – Tobias Mar 30 '15 at 06:35

3 Answers3

4

You need to implement a IComparer for String. See Use own IComparer<T> with Linq OrderBy. In the comparer, you can check if the first and string can be parsed to int and act accordingly. You have 4 cases to handle:

int, int

int, string

string, int

string, string

Case 1 and 4 are straightforward. In case 2 and 3 you decide if you want the ints first or vise versa.

Community
  • 1
  • 1
Tarik
  • 10,810
  • 2
  • 26
  • 40
2

You can try this:

var firstPart = originalItems.Where(x => !String.IsNullOrEmpty(x) && x.Page.All(char.IsDigit)).OrderBy(x => Convert.ToInt32(x.Page));
var secondPart = originalItems.Where(x => !String.IsNullOrEmpty(x) && !x.Page.All(char.IsDigit)).OrderBy(x => x.Page);
var thirdPart = originalItems.Where(x => String.IsNullOrEmpty(x)).ToList();

var result = firstPart.Union(secondPart).Union(thirdPart).ToList();
Farhad Jabiyev
  • 26,014
  • 8
  • 72
  • 98
  • I tried this but getting error Cannot convert type 'string' to 'int' here .OrderBy(x => (int)x.Page); Since my Page is of type String – Sebastian Mar 28 '15 at 05:48
  • @JMat Try my update. Does `originalItems` is a list? – Farhad Jabiyev Mar 28 '15 at 05:49
  • Yes Orignal is also a list and the update solves the problem .:) – Sebastian Mar 28 '15 at 05:52
  • we have to do a slight modification also . In case if Page property is null the current code returns exception . Now i am creating 2 seperate List 1. Null List & 1 Non Null List and then do the final union like this http://pastebin.com/9PiHCKB6 . Is any better way – Sebastian Mar 30 '15 at 06:23
1

I did it a little bit differently but got the same result

First I created an extension method

 public static class CollectionsUtils
{
    public static bool isPageIntegrable(this ModelItems modelItem)
    {
        int integrable = 0;
        bool result = Int32.TryParse(modelItem.Page,  out integrable);
        return result;
    }

....

This second method, I used to display the list

  public static void displayList<T>(this List<T> list)
    {
        Console.Write("[");
        foreach (T t in list)
        {
            Console.Write(t);
        }
        Console.WriteLine("]");
    }

Then I create the following DoSort method

 public void DoSort()
    {
        List<ModelItems> sorted_items = originalItems.Where(i => i.isPageIntegrable()).OrderBy(i => Int32.Parse( i.Page)).ToList();
        List<ModelItems> second_part = originalItems.Where(i => !i.isPageIntegrable()).OrderBy(i => i.Page).ToList();
        var final_sorted = sorted_items.Union(second_part).ToList();

        final_sorted.displayList();
        Console.ReadKey();
    }

The result: sort

alainlompo
  • 4,414
  • 4
  • 32
  • 41