WedX - журнал о программировании и компьютерных науках

Сортировка строкового массива в специальном стиле

что нам нужно сделать, если мы хотим отсортировать наш string Array в специальной форме?
Например, у нас есть это:

players = new string[12] {"soccer","12","man","swim","3","woman","volleyball","12","man","baseball","13","man"};

теперь мы хотим отсортировать Array по этой форме: (это просто мой порядок желаний и нет никакой логики)

sort = new string[4] {"swim","baseball","volleyball","soccer"}  

и, наконец, есть:

out = [{плавать,3,женщина},{бейсбол,13,мужчина},{волейбол,12,мужчина},{футбол,12,мужчина}]

26.06.2015

  • Извините, но я не понимаю вашей логики... Почему бы вместо этого не создавать объекты игрока? 26.06.2015
  • в чем логика? почему плавание предшествует бейсболу? Почему футбол идет после бейсбола? 26.06.2015
  • это не ИИ, должна быть какая-то логика для создания коллекции 26.06.2015
  • Описанное поведение не имеет ничего общего с сортировкой. Скорее это своего рода сопоставление, которое будет работать только с массивом players, имеющим особый порядок элементов, и не будет работать ни в каком произвольном случае. 26.06.2015
  • @Mivaweb этот массив получен из последовательной строки, и я преобразовываю его в массив. Теперь хочу подобрать его к своему заказу. Так понятно? что вы имеете в виду от объектов игрока? 26.06.2015
  • @EhsanDavoudi под серийной строкой вы подразумеваете одну единственную строку, а затем создаете из нее массив 26.06.2015
  • См. ответ @ Mivaweb. Не преобразовывайте его в массив строк, это только усложняет жизнь. Вместо этого преобразуйте его в список объектов игрока. 26.06.2015
  • Нет никакой логики, и у меня есть форма, которую я хочу заполнить этим заказом. теперь я хочу разобрать свой массив, чтобы облегчить его. 26.06.2015
  • Пожалуйста, уточните вашу конкретную проблему или добавьте дополнительные детали, чтобы выделить именно то, что вам нужно. В том виде, в котором он сейчас написан, трудно точно сказать, о чем вы спрашиваете. См. страницу Как спросить, чтобы уточнить этот вопрос. 26.06.2015
  • @ Дэвид Арно, не могли бы вы подсказать мне, как это сделать? Я могу понять, что вы имеете в виду. 26.06.2015
  • @EhsanDavoudi, прочитай ответ: он направляет тебя. 26.06.2015
  • @EhsanDavoudi проверь мой ответ. Если вы не можете использовать классы по какой-либо причине. 26.06.2015

Ответы:


1

В других ответах хорошо сказано о создании класса для хранения ваших данных, но это можно сделать и без него:

var ordered = Enumerable.Range(0, players.Length / 3)
.Select(i => new string[] { players[i*3], players[i*3+1], players[i*3+2] })
.OrderBy(a => Array.IndexOf(sort, a[0]))
.ToArray();

Если в массиве игроков есть виды спорта, которых нет в массиве сортировки, их можно отфильтровать.

var ordered = (from i in Enumerable.Range(0, players.Length / 3)
let index = Array.IndexOf(sort, players[i*3])
where index >= 0
select new string[] { players[i*3], players[i*3+1], players[i*3+2] }
).OrderBy(a => Array.IndexOf(sort, a[0])).ToArray();
26.06.2015
  • Надо сказать, довольно интересный подход 26.06.2015
  • хороший. но мои желательные элементы вошли последними в мой массив. В моем списке игроков есть еще один вид спорта, который мы не хотим показывать в моем результате. как 'Chess'. 26.06.2015

  • 2

    У вас есть один большой массив строк, который содержит все данные вашего игрока. Это не лучшее решение.

    Создайте объекты игрока, которые содержат все свойства, и поместите их в массив.

    Затем вы можете создать собственную сортировку.

    Объект игрока:

    public class Player {
         public string Type { get; set; }
         public string Gender { get; set; }
         public int AmountOfPlayers { get; set; }
         public int Order { get; set; }
    }
    

    Создайте массив объектов Player:

    List<Player> list = new List<Player>();
    list.Add(new Player() { Type = "swim", Gender = "women", AmountOfPlayers = 3, Order = 1 });
    list.Add(new Player() { Type = "soccer", Gender = "men", AmountOfPlayers = 12, Order = 4 });
    list.Add(new Player() { Type = "volleyball", Gender = "men", AmountOfPlayers = 12, Order = 3 });
    list.Add(new Player() { Type = "baseball", Gender = "men", AmountOfPlayers = 13, Order = 2 });
    

    Сортировка:

    var sortedList = list.OrderBy(c => c.Order);
    
    26.06.2015
  • сортировка неверна (у него есть специфическая сортировка... сначала игра, футбол в последнюю очередь)... и OrderBy не на месте... она возвращает новую отсортированную IEnumerable<> 26.06.2015
  • @Mivaweb, как сказал xanatos, это неправда. Потому что после сортировки по Type у нас не будет желаемого результата. 26.06.2015
  • Список‹Игроки› должен быть Список‹Игрок› 26.06.2015
  • @EhsanDavoudi, вы также можете установить дополнительное свойство Order, чтобы задать требуемый порядок вашего списка. Например, 1 = плавание, 2 = бейсбол, ... 26.06.2015

  • 3

    Хотя я бы предложил объектно-ориентированный подход, как показано другими. Однако на всякий случай из-за некоторых оговорок вы не можете этого сделать, тогда это сработает.

    string[] players = new string[15] {"soccer","12","man","swim","3","woman","volleyball","12","man","baseball","13","man"
        ,"chess","18","man"};
    string[] sort = new string[4] {"swim","baseball","volleyball","soccer"};
    string[] playersSorted= new string[sort.Length*3];
    int destStartIndex = 0;
    foreach(string str in sort)
    {
      int sourceStartIndex = Array.IndexOf(players,str);
      Array.Copy(players, sourceStartIndex, playersSorted, destStartIndex, 3);
      destStartIndex += 3;
    }
    

    ДЕМО

    26.06.2015
  • Просто имейте в виду, что Array.IndexOf — это операция O(n), где n — длина массива, если у вас всего несколько видов спорта, это, вероятно, нормально. 26.06.2015

  • 4

    Вы можете попробовать этот способ. Сначала создайте класс из исходного string[], который может представлять все значения в формате, показанном ниже:

    Class Sport
    {
       public string Name {get; set;}
       public int Number {get; set;}
       public string Gender {get; set;}
    }
    

    Когда у вас есть коллекция как List<Sport> sportList, теперь вам нужно создать пользовательскую IComparer для выполнения необходимой сортировки:

    class SportSorter : IComparer<Sport>
    {           
        public int Compare(Sport x, Sport y )
        {
            int retVal = 0;            
            retVal = string.Compare(x.Name,y.Name);
            return retVal;
        }
    }
    

    Теперь вы можете просто позвонить, используя экземпляр SportSorter

    SportSorter ss = new SportSorter();
    
    sportList.Sort(ss);
    

    Обратите внимание, что сейчас я использую свойство Name для сортировки, то же самое можно изменить в коде CustomSorter (IComparer). Это стабильная версия сортировки по сравнению с OrderBy, в которой используется QuickSort. Если вы хотите объединить несколько сортировщиков в разных направлениях, проверьте следующий ответ:

    Сортировка списка словарей с использованием IComparer вместо OrderBy

    Кроме того, использование Sort вместо OrderBy обеспечит сортировку одной и той же памяти, а не создание нового списка, как это делает OrderBy.

    26.06.2015

    5

    Код скопирован с Mivaweb:

    public class Player {
         public string Type { get; set; }
         public string Gender { get; set; }
         public int AmountOfPlayers { get; set; }
    }
    

    затем

    List<Player> list = new List<Player>();
    list.Add(new Player() { Type = "swim", Gender = "women", AmountOfPlayers = 3 });
    

    Мой код:

    public static readonly string[] Order = new string[4] {"swim","baseball","volleyball","soccer"};
    
    public static int OrderOf(string str)
    {
        int ix = Array.IndexOf(Order, str);
        if (ix == -1)
        {
            ix = int.MaxValue;
        }
        return ix;
    }
    

    Затем отсортируйте его:

    list.Sort((p, q) => OrderOf(p.Type).CompareTo(OrderOf(q.Type)));
    

    list.Sort() находится «на месте», поэтому он напрямую меняет list. Обратите внимание, что если присутствуют виды спорта, отличные от указанного в списке, они займут первые места в упорядоченном списке.

    OrderOf использует Array.IndexOf для поиска индекса вида спорта в массиве Order. Неизвестные виды спорта идут последними.

    26.06.2015

    6

    На самом деле это не какой-то вид, но все же, если вы хотите обработать эти данные, вы можете использовать следующий подход, который, тем не менее, не является хорошим подходом.

    string[,] outArray = new string[sort.Length, 3];
            for (int i = 0; i < sort.Length; i++)
            {
                int pos = Array.IndexOf(players, sort[i]);
                outArray[i, 0] = players[pos];
                outArray[i, 1] = players[pos + 1];
                outArray[i, 2] = players[pos + 2];
            }
    

    Используйте объекты, коллекции и лямбда/LINQ для эффективного решения, и я думаю, что все приведенные выше ответы следуют лучшему подходу.

    26.06.2015
    Новые материалы

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


    Для любых предложений по сайту: [email protected]