user957479
user957479

Reputation: 501

Sort a collection based on another collection

I have a collection of file names with part of the pathname being a specific word. I can order the collection like this :

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

But now, I want to sort not by alphabetical order on the pathname part but according to specific order given by another collection.

So let's say the pathname part can be "ATE", "DET" and "RTI". I have another string collection : {"DET", "ATE", "RTI"} that I want to use to sort the filenames so that after sorting, filenames appear with their partname in the order "DET" first, then "ATE", then "RTI". How do I achieve this -> need to use an own comparer ?

Upvotes: 7

Views: 2833

Answers (3)

Jodrell
Jodrell

Reputation: 35696

If your problem is as simple as you state and there are just 3 possible prefixes you could do this.

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;
});

Upvotes: 0

xanatos
xanatos

Reputation: 111820

Three different variants, depending if you want to use string[], List<string> or a Dictionary<string, int> (good only if you have MANY elements 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'll add that LINQ doesn't have a "generic" IndexOf method, but you can build one as written here How to get index using LINQ?

Upvotes: 2

Rikard Pavelic
Rikard Pavelic

Reputation: 496

This should work

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

Upvotes: 8

Related Questions