2014-01-12 8 views
0

Я новичок в C# и стараюсь сделать это правильно. Я выполнил поиск stackoverflow и посоветовался с учебниками и книгами «сортировать объекты класса», но пока не нашел ничего, что работает для меня, несмотря на борьбу с LISTS, INUMERATORS и COMPARATORS. Чтобы помочь мне учиться C# Я пытаюсь воспроизвести старую настольную игру. Он включает карты, которые нужно сортировать или перетасовывать в начале новой игры. Я получаю данные карты через хранимую процедуру от SQL Server, потому что я пытаюсь справиться с этим. Как я могу просто отсортировать объекты класса карты и ВОЗВРАТИТЬ их из моей функции ниже? Я даже собираюсь решить эту задачу наилучшим образом? Ниже приведен мой класс «PirateCard». Большое спасибо.Как отсортировать массив объектов класса?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Data; 
using System.Collections; 

namespace Buccaneer 
{ 
    public class PirateCard : Card 
    { 


     public PirateCard() 
     { 
     } 

     public PirateCard[] initCards() 
     { 
      string spName = "sp_select_cards_by_type"; 
      int cardCount = 1; 
      db DB = new db(); 
      DataTable dt = new DataTable(); 

      Dictionary<string, string> spParams = new Dictionary<string, string>(); 
      spParams.Add("@Type", "PIRATE"); 

      dt = DB.executeSelectStoredProcedureWithParams(spName, spParams); 
      PirateCard[] pirateCards = new PirateCard[dt.Rows.Count + 1]; 

      List<int> sortNumber = shuffle(); 
      Console.WriteLine(sortNumber.Count); 

      foreach (DataRow row in dt.Rows) 
      { 
       pirateCards[cardCount] = new PirateCard(); 
       pirateCards[cardCount].Type = row["fldtype"].ToString(); 
       pirateCards[cardCount].Number = row["fldno"].ToString(); 
       pirateCards[cardCount].SortNumber= sortNumber.ElementAt(cardCount - 1); 
       pirateCards[cardCount].IncentiveType = row["fldincentivetype"].ToString(); 
       pirateCards[cardCount].Value = row["fldvalue"].ToString(); 
       pirateCards[cardCount].PlayWithin = row["fldplaywith"].ToString(); 
       pirateCards[cardCount].Text = row["fldtext"].ToString();   
       Console.WriteLine(pirateCards[cardCount].Number + ":" + pirateCards[cardCount].SortNumber); 
       cardCount++; 
      } 
      Console.WriteLine(DB.RecordCount + " pirate cards were found."); 
      // SHUFFLE OR SORT CARDS on .SortNumber here... 
      // ??? 
      return pirateCards; 
     } 

     public List<int> shuffle() 
     { 
      Random randNum = new Random(); 
      List<int> numbers = new List<int>(); 
      while (numbers.Count < ApplicationGlobals.numberOfPirateCards) 
      { 
       int num = randNum.Next(1, ApplicationGlobals.numberOfPirateCards + 1); 
       if (numbers.Contains(num)) 
       {      
       } 
       else 
       { 
        numbers.Add(num); 
        Console.WriteLine(num + " Numbers allocated so far " + numbers.Count); 
       } 
      } 
      Console.WriteLine(numbers.Count + " random numbers allocated"); 
      return numbers; 
     } 


    } 
} 

ответ

2

Вы можете отсортировать карты с помощью метода расширения LINQ OrderBy. Я предполагаю, что вы хотите, чтобы ваши карты отсортировались на основе их SortNumber.

return pirateCards.OrderBy(card => card.SortNumber).ToArray(); 

Edit: На второй мысли, вы должны избавиться от вашего shuffle метода (и SortNumber собственности), а также использовать первый метод расширения, предоставляемый из this answer, который основан на Fisher–Yates shuffle. Вы можете вызвать его с помощью:

return pirateCards.Shuffle(); 
+0

Большое спасибо за удивительно быстрый ответ. Я пробовал что-то такое, и просто сделал. Но я получаю ... Ссылка на объект не установлена ​​в экземпляр объекта. – user3187383

+0

@ user3187383: Да, это потому, что ваш массив на один элемент больше, чем количество карт (поэтому последний элемент остается «null»). Замените 'new PirateCard [dt.Rows.Count + 1]' на 'новый PirateCard [dt.Rows.Count]'. – Douglas

0

Если вы хотите придерживаться массива, существуют различные перегрузки метода Array.Sort. некоторые берут сравнение в качестве параметра, например .:

Array.Sort(pirateCards, (x, y) => x.SortNumber - y.SortNumber); 

Кстати, ваш массив является одним из элементов в целом; вы должны инициализировать его следующим образом, чтобы избежать NullReferenceException при сортировке:

PirateCard[] pirateCards = new PirateCard[dt.Rows.Count]; 

Кроме того, cardCount потребности быть initilized со значением 0, как массивы начинаются с 0 в .NET.

+0

Большое спасибо обоим. Я играл с инициализацией массива и приращением, теперь я изменил код, чтобы запустить массив на нуле (cardCount), и избежать необходимости добавлять 1 или вычитать один в разных точках. Намного проще! – user3187383

0

Вы можете сэкономить много времени, используя "LinQ to SQL Classes", который преобразует ваши таблицы базы данных в классы. Затем вы можете сортировать и группировать массив объектов в простом коде.

+0

Я видел некоторые вещи о LINQ и буду исследовать, спасибо. – user3187383

Смежные вопросы