2

I need to find out how to sort some data by pre-defined pattern.

Lets say I have some strings, which represents product informafion, e. g.

Product1, red, 70/n

Product6, blue, 90/n

Product3, red, 50/n

Product9, white, 33/n

I separated these strings by coma string split and stored them at different Arrays (name, color, price) and then DataTable with same columns.

I can order created rows by color using :

DataView.sort = "color" 

or by LINQ with

DataRow[] dr = table.Select().OrderBy(u=>u[color]).ToArray();
DataTable sortedtable = dr.CopyToDataTable(); 

However this is just simple sorting, asc/desc, based on alphabet.

I would like to achieve sorting with pre-defined pattern. In example the item order would be defined by colors in order red, black, blue, white.

Is there anything simple I could do? I think this is possible with checking each row color and comparing it with predefined color list, then building new Array / DataTable based on this order. However I feel that this is weak approach.

1
  • Sorry, it was just part of the code to give general idea, actually I was writing on my phone, but the full code is: DataRow[] dr = table.Select().OrderBy(u=>u[color]).ToArray(); DataTable sortedtable = dr.CopyToDataTable(); Commented Nov 23, 2018 at 8:51

5 Answers 5

5

You could store the order in another collection and then use IndexOf:

var colorOrderList = new List<string>{"red", "black", "blue", "white"};
table = table.AsEnumerable()  
    .OrderBy(row => colorOrderList.IndexOf(row.Field<string>("color")))
    .CopyToDataTable();
Sign up to request clarification or add additional context in comments.

1 Comment

And if the ordered list was much longer, you could use a Dictionary<string, int> to map the strings onto a rank to reduce an O(N) operation within the sort to an O(1) one (where N = number of ranked strings, not the number of strings being sorted).
1

You can define n ordering array like

var order = new [] { "red", "blue", "white"};

and then use IndexOf

DataRow.Select().OrderBy(u=>Array.IndexOf(order, u[color]))

3 Comments

If you store the order in an array, you need to use Array.IndexOf, there's no extension. Also, DataTable.Select returns a fresh DataRow[]. It's pontless to order that without re-assigning it to the table somehow
May wish to highlight the unknown colours will be sorted first with this. (Not proposing you need to add all the options for dealing with this if it's not desired, just mention it)
Thank you very much guys, amazing answers, helped a lot. I definitely need to learn about LINQ
0

Use IComparable to make a custom sort order. https://support.microsoft.com/en-ca/help/320727/how-to-use-the-icomparable-and-icomparer-interfaces-in-visual-c

Comments

0

Products.OrderBy(u => u == "Red" ? 0 : u == "Black" ? 1 : u == "Blue" ? 2 : 3)

has the advantage that it should be translatable to a SQL statement so that the database server can do the sorting.

Comments

0

You can use IComaparable. First create a custom class which can accommodate your product details. Make this class implement the IComparable interface.

 public class ProductDetails : IComparable
    {
        public int ProductId { get; set; }
        public int CompareTo(object obj)
        {
            ProductDetails prodDetails = obj as ProductDetails;
            if (obj == null) return 1;

            if (prodDetails != null)
            {
                if (this.ProductId < prodDetails.ProductId) return 1;
                else
                    return 0;

            }
            else {
                return 0;
            }

        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.