Order List items based on other List

leorob88

Well-known member
Joined
Dec 31, 2020
Messages
56
Programming Experience
1-3
I have a Class. I'm creating a List of items that are based on that class. Like, Class Fruit and List<Fruit> fruits. Now, I'm creating another List for the same Class type. Is there a simple straight instruction (method/function) to order the items in the second List based on the index they have in the first main List?
Like, I don't want to order them in alphabetical order or such basic concepts, I want to have a specific order of the items in the first List and when I finish creating the second List, which items are all contained in the first List, I want to order the items in this new List like they would be ordered in the first one (so, basically, by their index).
Note that in this second List the items can occur more than once. A useful info can be the fact that, for example, a Fruit can have a name property (if a property is needed to do this).
So if my first List is just a general List of Fruit, having each one a name, like,

fruits[0] -> item having name "Strawberry"
fruits[1] -> item having name "Banana"
fruits[2] -> item having name "Pear"

and my second list will be like

secList[0] -> item having name "Pear"
secList[1] -> item having name "Strawberry"
secList[2] -> item having name "Banana"
secList[3] -> item having name "Banana"

i want the second list to become ordered like this:

secList[0] -> item having name "Strawberry"
secList[2] -> item having name "Banana"
secList[3] -> item having name "Banana"
secList[1] -> item having name "Pear"
 
Obviously, you need to get the index of an item in the fruits list based on the Name of an item from the secList list. To do that, you can use the FindIndex method of that list. This is something that you should already know because you should have read the documentation for the List<T> class and seen that method for yourself. There's then multiple ways you could use that. The Sort method the fruits list will sort in place, which you should also already know from the documentation, or you could use a LINQ query with an OrderBy clause to create a new list to replace the old. Here's an example of the former:
C#:
internal class Program
{
    static void Main()
    {
        var fruits = new List<Fruit>
                        {
                            new Fruit { Name = "Strawberry" },
                            new Fruit { Name = "Banana" },
                            new Fruit { Name = "Pear" }
                        };
        var secList = new List<Fruit>
                        {
                            new Fruit { Name = "Pear" },
                            new Fruit { Name = "Strawberry" },
                            new Fruit { Name = "Banana" },
                            new Fruit { Name = "Banana" }
                        };

        Console.WriteLine("Before sort:");

        foreach (var fruit in secList)
        {
            Console.WriteLine(fruit.Name);
        }

        secList.Sort((f1, f2) => fruits.FindIndex(f => f.Name == f1.Name).CompareTo(fruits.FindIndex(f => f.Name == f2.Name)));

        Console.WriteLine("After sort:");

        foreach (var fruit in secList)
        {
            Console.WriteLine(fruit.Name);
        }

        Console.ReadLine();
    }
}

class Fruit
{
    public string? Name { get; set; }
}
I suggest that you make use of your F1 key to open the documentation for some of those methods to see exactly what overloads are being called and how they work. Both Sort and FindIndex are taking lambda expressions as arguments, but you could write named methods to do the same thing if you're not au fait with LINQ.

One point to note is that this is an unstable sort. That means that the order in which duplicates appear in the sorted list is not specifically defined. They may appear in the same order as in the original or some or all may swap places. It may be the case that you want duplicates to appear in the sorted list in the same order as they appear in the original list, in which case you'd have to provide your own logic to enforce that.
 
I don't understand by which logic you make the whole thing seem so obvious to realize when in the end you didn't even do it (?). Like, literally, you provided a tip stating at the end that this is a "half tip" since it's likely it won't work for my purpose. So, I don't see how someone can say "Hey, you're so dumb, this is how it's done, it's so easy! Except, like this, it actually doesn't work well." ... Wtf?
 
Because that would be spoon feeding you the answer. This is not a gimme-the-codez site. This site is meant to engage your brain and lead you to an answer by having you actively participate in your learning.
 
I don't understand by which logic you make the whole thing seem so obvious to realize when in the end you didn't even do it (?). Like, literally, you provided a tip stating at the end that this is a "half tip" since it's likely it won't work for my purpose. So, I don't see how someone can say "Hey, you're so dumb, this is how it's done, it's so easy! Except, like this, it actually doesn't work well." ... Wtf?

I'm not even sure what you're saying here. I'm guessing that you're not happy that I said that you should already know some things, but that is absolutely the case. Obviously, there's going to be a lot of things about programming in general and the language and technologies you're using specifically that you don't know when you're a relative beginner. That doesn't mean that you're helpless though. Visual Studio has a Help menu, just like the vast majority of sizeable Windows applications. It doesn't take any programming experience to use the Help menu when you need help and it should be one of the very first things you do, if not THE first. VS also supports context-sensitive Help, which has been a thing in Windows for decades. You can click a type or member name in the code window and press F1 to be taken directly to the documentation for that type or member. These are things that anyone can and should do for themselves. You won't find everything that you need or understand everything that you find but you will find a lot that will be useful at the time and/or later on. I know this because it's exactly what I did when learning VB.NET and C#. I had a comp. sci. degree so I understood many programming principles but I'm self-taught as far as .NET is concerned and much of what I learned came from the official documentation. You have no idea how many times I've answered questions on sites like this one, on subjects that I was completely unfamiliar with, simply by reading the relevant documentation that the person asking the question could have read for themselves but didn't. ALWAYS read the relevant documentation. If you haven't then you haven't really done all you can to solve the problem yourself before asking others to do it for you. In this specific case, I very much doubt that you would have been able to do the whole thing yourself but you would have been able to get part of the way there and then ask a more specific question.

As for what I provided, it's not a "half tip" at all. It does exactly what you asked for. I did ALL your work for you. Did you even test the code I provided? I then said that if you wanted some additional functionality that you DID NOT ask for then you'll have to do some extra work. I'm not going to do that work here when you didn't ask for it and I have no idea whether you actually need it. Unstable sorts are the norm and are fine in the vast majority of situations, so why would I assume that it wasn't in your case? If you need a stable sort then you can say so (which you haven't actually done even now, so I'm still not sure whether you need it) and I would be willing to help you implement it. Nothing I've said or done has ruled that out, but I'm far less inclined to do so now, given your seemingly entitled response.

If you do need a stable sort then, as I said, I'd probably be prepared to help, but I'd want to see some effort on your part first, rather than your just telling us what you want and sitting back and waiting for it to be done for you. Again, there will obviously be a lot that you don't know about programming and that's fine, but that doesn't mean that you're helpless. Code is simply a formal implementation of logic and we all use logic every day of our lives. You don't need any programming experience to work out the logic required to perform any particular task so even a rank beginner can do that. You can then formalise that logic into an algorithm that you can test manually, e.g. by writing a list of values on a piece of paper and sorting them on that paper. Once you have a working algorithm, you can the write corresponding pseudo-code. That's what you get taught in a programming class. Programming knowledge can help here but the language doesn't matter and even a relative beginner can write conditional statements, loops, etc, in pseudo-code. Finally, you would write the actual code to implement the logic based on the pseudo-code. If you encounter a problem at any point, you can ask a specific question and show us exactly where you're stuck in your pseudo-code and algorithm, so we can see what logic it is that you're having trouble implementing. This would be ideal but, generally speaking, we're not going to expect you to have been so rigorous. We would like to see at least some effort on the logic part though.
 
I wish to point out that thanks to these indexes being teh way they are, you're requesting a list output of "Strawberry, Pear, Banana, Banana", which is not the order of the 3 item list
1717477758369.png


To sort a second array by a first, it's easier (and faster) to make a mapping of name to position:

C#:
var map = first.Select((f, i) => (Name: f.Name, Index: i)).ToDictionary(t => t.Name, t => t.Index);

This dictionary will map names to indexes. This means you can then just map a name to a number when ordering:

C#:
second.OrderBy(f => map[f.Name]);

Actually your list seems to be descending, but.. exercise for the reader
 
Back
Top Bottom