AKA
AKA

Reputation: 27

Sorting List Array based on an index of array

I want to sort a List Array on the basis of an array item. I have a List Array of Strings as below:

List<String>[] MyProjects = new List<String>[20];

Through a loop, I have added five strings

(Id, Name, StartDate, EndDate, Status)

to each of the 20 projects from another detailed List source.

for(int i = 0; i<20; i++){
MyProjects[i].Add(DetailedProjectList.Id.ToString());
MyProjects[i].Add(DetailedProjectList.Name);
MyProjects[i].Add(DetailedProjectList.StartDate);
MyProjects[i].Add(DetailedProjectList.EndDate);
MyProjects[i].Add(DetailedProjectList.Status)}

The Status values are

"Slow", "Normal", "Fast", "Suspended" and "" for unknown status.

Based on Status, I want to sort MyProject List Array.

What I have done is that I have created another List as below

List<string> sortProjectsBy = new List<string>(){"Slow", "Normal", "Fast", "", "Suspended"};

I tried as below to sort, however unsuccessful.

MyProjects = MyProjects.OrderBy(x => sortProjectsBy.IndexOf(4));

Can anyone hint in the right direction. Thanks.

Upvotes: 0

Views: 85

Answers (5)

Ido Bleicher
Ido Bleicher

Reputation: 857

First consider maybe to use Enum for status and put it in a different file lite (utils or something) - better to work like that.

enum Status {"Slow"=1, "Normal", "Fast", "", "Suspend"}

Now about the filtering you want to achieve do it like this (you need to tell which attribute of x you are referring to. In this case is status)

MyProjects = MyProjects.OrderBy(x => x.status == enum.Suspend);

Read about enums : https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/enum

Read about lambda expressions : https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions

Upvotes: 1

M.Hazara
M.Hazara

Reputation: 137

Lets say you have ProjectDetail class as follow:

        private class ProjectDetail
    {
        public int Id {get;set;}
        public string Name {get;set;}
        DateTime StartDate {get;set;} = DateTime.Now;
        DateTime EndDate {get;set;} = DateTime.Now;
        public string Status {get;set;}
        public string toString => $"{Id} - {Name} - {StartDate} - {EndDate} - {Status}";
    }

Notice that I have added a toString attribute to make things easier, and I also have added default values.

Then your program could be like:

static void Main(string[] args)
    {
        var projectDetails = MockProjectItems();
        Console.WriteLine("Before sortig:");
        foreach (var item in projectDetails)
        {
            Console.WriteLine(item.toString);
        }
        var myProjects = projectDetails.OrderBy(p => p.Status).Select(p => p.toString);
        Console.WriteLine("\n\nAfter sorting:");
        foreach (var item in myProjects)
        {
            Console.WriteLine(item);
        }
    }

where the helper method is

        private static List<ProjectDetail> MockProjectItems()
    {
        var items = new List<ProjectDetail>(20);
        for(int i = 0; i < 20 ; i += 4){
            items.Add(new ProjectDetail{Id = i, Name = "RandomName "+i, Status = "Slow"});
            items.Add(new ProjectDetail{Id = i+1, Name = "RandomName "+(i+1), Status = "Normal"});
            items.Add(new ProjectDetail{Id = i+2, Name = "RandomName "+(i+2), Status = "Fast"});
            items.Add(new ProjectDetail{Id = i+3, Name = "RandomName "+(i+3), Status = "Suspended"});
        }
        return items;
    }

Then your program should print the following: enter image description here

Upvotes: 0

M.Hazara
M.Hazara

Reputation: 137

Ok so you have a collection of 20 items. Based on them you need to create a list of strings(20 DetailedProjectList items).

What you can do to solve your problem is to SORT YOUR COLLECTION before you create your list of strings. In this way your list of strings will be sorted.

But your code is not optimal at all. So you should concider optimization on many levels.

Upvotes: 0

Anu Viswan
Anu Viswan

Reputation: 18155

First of all, storing project details as List is not adivisable. You need to create a Custom Class to represent them. For example,

public class DetailedProjectList
{
    public string Name {get;set;}
    public eStatus Status {get;set;}
    // rest of properties
}

Then You can use

var result = MyProjects.OrderBy(x=> sortProjectsBy.IndexOf(x.Status));

For example

List<string> sortProjectsBy = new List<string>(){"Slow", "Normal", "Fast", "", "Suspended"};
var MyProjects= new List<DetailedProjectList>{
new DetailedProjectList{Name="abc1", Status="Fast"},
new DetailedProjectList{Name="abc2", Status="Normal"},
new DetailedProjectList{Name="abc3", Status="Slow"},
};

var result = MyProjects.OrderBy(x=> sortProjectsBy.IndexOf(x.Status));

Output

abc3 Slow 
abc2 Normal 
abc1 Fast 

A better approach thought would be to use Enum to represent Status.

public enum eStatus
{
    Slow,
    Normal,
    Fast,
    Unknown,
    Suspended

}

Then your code can be simplified as

    var MyProjects= new List<DetailedProjectList>{
    new DetailedProjectList{Name="abc1", Status=eStatus.Fast},
    new DetailedProjectList{Name="abc2", Status=eStatus.Normal},
    new DetailedProjectList{Name="abc3", Status=eStatus.Slow},
    };

    var result = MyProjects.OrderBy(x=> x.Status);

Upvotes: 0

AndrejH
AndrejH

Reputation: 2109

I suggest you to create class Project and then add all the fields inside it you need. It's much nicer and scalable in the future. Then create a List or an Array of projects and use the OrderBy() function to sort based on the field you want.

List<Project> projects = new List<>();
// Fill the list...
projects.OrderBy(project => project.Status);

The field Status has to be a primitive type or needs to implement the interface IComparable in order for the sorting to work. I suggest you add an enum for Status with int values.

Upvotes: 2

Related Questions