Сортировка массива списка на основе индекса массива - PullRequest
0 голосов
/ 06 января 2019

Я хочу отсортировать массив списков на основе элемента массива. У меня есть список массивов строк, как показано ниже:

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

Через цикл я добавил пять строк

(идентификатор, имя, начальная дата, конечная дата, состояние)

к каждому из 20 проектов из другого подробного списка источников.

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

Значения статуса:

«Медленно», «Нормально», «Быстро», «Приостановлено» и «» для неизвестного статуса.

На основе статуса я хочу отсортировать массив списков MyProject.

Я сделал еще один Список, как показано ниже

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

Я попытался выполнить сортировку, как показано ниже, но безуспешно.

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

Может кто-нибудь намекнуть в правильном направлении. Спасибо.

Ответы [ 5 ]

0 голосов
/ 06 января 2019

Допустим, у вас есть класс ProjectDetail следующим образом:

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

Обратите внимание, что я добавил атрибут toString, чтобы упростить задачу, а также добавил значения по умолчанию.

Тогда ваша программа может выглядеть так:

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

где вспомогательный метод

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

Тогда ваша программа должна напечатать следующее: enter image description here

0 голосов
/ 06 января 2019

Хорошо, у вас есть коллекция из 20 предметов. На их основе необходимо создать список строк (20 элементов DetailProjectList).

Что вы можете сделать, чтобы решить вашу проблему, так это отсортировать коллекцию перед созданием списка строк. Таким образом, ваш список строк будет отсортирован.

Но ваш код совсем не оптимален. Таким образом, вы должны проводить оптимизацию на многих уровнях.

0 голосов
/ 06 января 2019

Я предлагаю вам создать класс Project, а затем добавить в него все необходимые поля. Это намного лучше и масштабируемо в будущем. Затем создайте List или Array проектов и используйте функцию OrderBy() для сортировки по нужному полю.

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

Поле Status должно быть примитивного типа или должно реализовывать интерфейс IComparable, чтобы сортировка работала. Я предлагаю вам добавить enum для Status со значениями int.

0 голосов
/ 06 января 2019

Сначала рассмотрите возможность использования Enum для статуса и поместите его в другой файл lite (utils или что-то в этом роде) - лучше так работать.

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

Теперь о фильтрации, которую вы хотите добиться, сделайте это следующим образом (вам нужно указать, на какой атрибут x вы ссылаетесь. В данном случае это статус)

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

Читайте о перечислениях: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/enum

Читайте о лямбда-выражениях: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions

0 голосов
/ 06 января 2019

Прежде всего, хранение деталей проекта в виде Списка невозможно. Вам необходимо создать пользовательский класс для их представления. Например,

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

Тогда вы можете использовать

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

Например

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

Выход

abc3 Slow 
abc2 Normal 
abc1 Fast 

Лучше всего было бы использовать Enum для представления статуса.

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

}

Тогда ваш код можно упростить до

    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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...