Sorting a collection based on another collection

I have a collection of file names, and part of the path name is specific. I can order the collection as follows:

var files = from f in checkedListBox1.CheckedItems.OfType<string>()
            orderby f.Substring(0,3)
            select f;

But now I want to sort not alphabetically in part of the path, but in accordance with a specific order specified by another collection.

So, let part of the path be “ATE”, “DET” and “RTI”. I have another collection of strings: {"DET", "ATE", "RTI"}, which I want to use to sort the file names so that after sorting, the file names with their name in the order of "DET" are displayed first, then "ATE ", then" RTI ". How do I achieve this → do I need to use my own comparator?

+5
source share
3 answers

Three different options, depending on whether you want to use string[], List<string>or Dictionary<string, int>(well, only if you have LOTS of items to search for)

string[] collection = new[] { "DET", "ATE", "RTI" };
var files = from f in checkedListBox1.CheckedItems.OfType<string>()
            orderby Array.IndexOf(collection, f.Substring(0, 3))
            select f;

List<string> collection2 = new List<string> { "DET", "ATE", "RTI" };
var files2 = from f in checkedListBox1.CheckedItems.OfType<string>()
            orderby collection2.IndexOf(f.Substring(0, 3))
            select f;

Dictionary<string, int> collection3 = new Dictionary<string, int> 
            { { "DET", 1 }, { "ATE", 2 }, { "RTI", 3 } };

Func<string, int> getIndex = p =>
{
    int res;
    if (collection3.TryGetValue(p, out res))
    {
        return res;
    }
    return -1;
};

var files3 = from f in checkedListBox1.CheckedItems.OfType<string>()
                orderby getIndex(f.Substring(0, 3))
                select f;

I will add that LINQ does not have a “common” method IndexOf, but you can build it as written here How to get the index using LINQ?

+2
source

This should work

var files = from f in checkedListBox1.CheckedItems.OfType<string>()
        orderby anotherCollection.IndexOf(f.Substring(0,3))
        select f;
+6
source

If your problem is as simple as you state, and there are only three possible prefixes, you can do it.

var fileNames = checkedListBox1.CheckedItems.OfType<string>();
var files = fileNames.OrderBy(f => 
{
    int value = int.MaxValue;
    switch (f.Substring(0, 3))
    {
        case "DET":
            value = 1;
            break;
        case "ATE":
            value = 2;
            break;
        case "RTI":
            value = 3;
            break;
    }
    return vakue;
});
0
source

All Articles