user3187383
user3187383

Reputation: 139

How to sort an array of class objects?

I am new to c# and attempting to do it the right way. I have searched stackoverflow and consulted tutorials and books re 'sorting class objects' but have yet to find anything that works for me, despite struggling with LISTS, INUMERATORS and COMPARATORS. To help me learn c# I am attempting to replicate an old board game. It includes Cards that need to be sorted or shuffled on the start of a new game. I'm getting the card data via a stored procedure from SQL Server because I am trying to get to grips with that as well. How can I simply sort my card class objects and RETURN them from my function below? Am I even going about this task in the best way? Below is my 'PirateCard' class. Many thanks.

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


    }
}

Upvotes: 0

Views: 249

Answers (3)

Douglas
Douglas

Reputation: 54887

You can sort the cards using the LINQ OrderBy extension method. I'm assuming you want your cards sorted based on their SortNumber property.

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

Edit: On second thoughts, you should do away with your shuffle method (and SortNumber property), and use the first extension method provided from this answer, which is based on the Fisher–Yates shuffle. You can call it using:

return pirateCards.Shuffle();

Upvotes: 2

Zein Makki
Zein Makki

Reputation: 30042

You can save a lot of time by using "LinQ to SQL Classes" that will convert your database tables to classes. Then you can sort and group your array of objects in simple code.

Upvotes: 0

Markus
Markus

Reputation: 22481

If you want to stick with the array, there are various overloads of the Array.Sort method. some take a Comparison as a parameter, e.g.:

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

By the way, your array is one element to large; you should initialize it as follows to avoid a NullReferenceException when sorting:

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

Also, cardCount needs to be initilized with a value of 0 as arrays start with 0 in .NET.

Upvotes: 0

Related Questions