Dear people of DaniWeb!
I am in trouble.
I can't figure this out

I have a text file

Five Finger Death Punch – 'Under and Over It':30
Staind – 'Not Again':23
Breaking Benjamin – 'Blow Me Away':56
Theory of a Deadman – 'Lowlife':33
Anthrax – 'The Devil You Know':120

Like this. I want to sort it according to votes a song got. Example

Anthrax – 'The Devil You Know':120
Breaking Benjamin – 'Blow Me Away':56
Theory of a Deadman – 'Lowlife':33
Five Finger Death Punch – 'Under and Over It':30
Staind – 'Not Again':23

Thank you in advance guys!

Recommended Answers

All 8 Replies

What have you tried so far? Show us whatever you've written to solve this problem, and we'll try to point you in the right direction.

Sure. Please note I can't use classes or Lists. Yes, its a school project, the program is longer than this and this is the only part I can't get my hands on...

I've tried getting all the txt file into 1 array and then that into 2 1d arrays. I know every second row is a song so that sorting isn't hard.
Then I've tried using Array.Sort (votes, songName) //votes work as keys.

But right now I can't understand why Sort method returns the wrong Lengths of the arrays...

public static string[] RazvrstiPoVrsti(string povezava)
        {
            string[] nerazvrscenaLestvica;
            char[] locila = { ':', '\n' }; //locila za ločevanje vrstic
            StreamReader beri = File.OpenText(povezava); //odpremo datoteko

            nerazvrscenaLestvica = beri.ReadToEnd().Split(locila); //ločimo vrstice, dobimo tabelo velikosti 20
            Console.Write(nerazvrscenaLestvica.Length);
            if (nerazvrscenaLestvica.Length % 2 != 0)
            {
                Console.WriteLine("NAPAKA V DATOTEKI, PREVERI PRVO DATOTEKO!!!PROGRAM SE BO KONČAL");
                Console.ReadKey();
                Environment.Exit(0);
            }

            int dolzina = nerazvrscenaLestvica.Length / 2;
            string[] imeKomada = new string[dolzina]; //tukaj notri bodo imena pesmi, 
            int[] stGlasov = new int[dolzina];//tukaj notri bodo glasovi ki jih je posamezna pesem dobila

            int z = 0;//stevca za vpisovanje v posamezno tabelo
            int j = 0;

            for (int i = 0; i < nerazvrscenaLestvica.Length; i++) //razvrstimo nerazvrsceno tabelo na svoja mesta
            {
                int stevec = i;
                string trenVrst = nerazvrscenaLestvica[stevec];
                if (stevec % 2 == 0) //vsaka soda vrstica vemo da je pesem, zato vsako drugo vrstico damo v tabelo komadov
                {

                    imeKomada[j] = trenVrst;
                    j++;
                }
                else
                {
                    stGlasov[z] = int.Parse(trenVrst); //ostale damo v tabelo intov za stevilo glasov
                    z++;
                }
            }
            beri.Close();
            Array.Sort(stGlasov, imeKomada);//metoda posortira komade po stGlasov. stGlasov deluje kot ključ, kasneje glasov ne potrebujemo več ker iščemo skok.
            return imeKomada;

This is the method I'm trying to use (commented in Slovenian language, sorry)
So the sort method should return an array of length "dolzina" but it doesnt. When I use the method in my main and get that length its completley different (both of the arrays have different length - one 23, one 24, when both should be 10!).
So the problem is now a bit different than in my opened topic, that's because I didn't want you guys to solve everything for me, just point me in the right direction. I have to know what I write because im going to be explaining later.

Try SortByInt

like

struct Highscore
{
    public string Name;
    public int Score;
    public string Date;

    public string DataAsString()
    {
        return Name + "," + Score.ToString() + "," + Date;
    }
}

var sortedList = yourList.OrderBy(x => x.Score);

@nesa24casa He said he can't use classes. Structs are essentially the same thing (minus the allocation on the heap), so I doubt he could use them.

I ran a quick test with:

string[] ret = RazvrstiPoVrsti("c:\\test.txt");
Console.WriteLine(ret.Length);

for (int i = 0; i < ret.Length; i++)
    Console.WriteLine(ret[i]);

Console.ReadKey(true);

and it gave me the following output:

5
Staind ? 'Not Again'
Five Finger Death Punch ? 'Under and Over It'
Theory of a Deadman ? 'Lowlife'
Breaking Benjamin ? 'Blow Me Away'
Anthrax ? 'The Devil You Know'

I don't see where the arrays (imeKomada and stGlasov) are giving incorrect lengths. Could you post the code you are calling this method with, the actual output and the expected output.

I like the song list :)

What happens if two songs have identical votes? Whats the sort done on then?

To be honest, I got a little confused by your logic. Therefore I thought I would post this example. It is similar to yours and maybe you can use it to find the problem in your code.

string path = Application.StartupPath + "\\songs.txt";
System.IO.Stream strmSongs = System.IO.File.OpenRead(path);
System.IO.StreamReader sr = new System.IO.StreamReader(strmSongs);

string[] Songs = new string[100];            //initially allow for 100 songs
Int32[] Votes = new Int32[100];
string line = null;

Int32 count = 0;
while (sr.Peek() != -1)
{
    line = sr.ReadLine();
    string[] parts = line.Split(':');
    if (parts.Length != 2)
    {
        //bad line of data

    }
    else
    {
        if (count == Votes.Length)
        {
            //array is not big enough, make room for 20 more entries
            Array.Resize(ref Songs, Songs.Length + 20);
            Array.Resize(ref Votes, Votes.Length + 20);
        }
        Songs[count] = line;
        Votes[count] = Int32.Parse(parts[1]);
        count += 1;
    }

}

//trim the arrays if necessary
if (count != Songs.Length)
    Array.Resize(ref Songs, count);
if (count != Votes.Length)
    Array.Resize(ref Votes, count);

sr.Close();

Array.Sort(Votes, Songs);

I did it a different way yet again, probably more inefficient but still works.

    class Program
    {
        static string[] LinesOfTextFile;
        static string[] SortedList = new string[5];

        static void Main(string[] args)
        {
            Console.WriteLine("Starting the sort.");
            Console.WriteLine();
            string[] OutputOfSort = RipFileAndSort(@"C:\Users\maskew\Desktop\Test.txt");
            Console.WriteLine();
            Console.WriteLine("Finished the sort.");
            Console.WriteLine();
            foreach (string TextString in OutputOfSort)
            {
                Console.WriteLine(TextString);
            }
            Console.ReadLine();
        }

        public static string[] RipFileAndSort(string FilePath)
        {
            StreamReader FileReader = File.OpenText(FilePath);
            LinesOfTextFile = FileReader.ReadToEnd().Split('\n');
            for (int i = 0; i < LinesOfTextFile.Length; i++)
            {
                int VotesReceived = GetVoteNumber(LinesOfTextFile[i]);
                for (int j = 0; j < SortedList.Length; j++)
                {
                    if (SortedList[j] == null)
                    {
                        SortedList[j] = LinesOfTextFile[i];
                        break;
                    }
                    else
                    {
                        if (VotesReceived > GetVoteNumber(SortedList[j]))
                        {
                            InsertStringIntoArrayAbove(LinesOfTextFile[i], j);
                            break;
                        }
                    }
                }
            }
            return SortedList;
        }

        public static void InsertStringIntoArrayAbove(string StringToInsert, int PositionToInsertInto)
        {
            string HoldingLocationOne = null;
            string HoldingLocationTwo = null;
            HoldingLocationOne = SortedList[PositionToInsertInto];
            SortedList[PositionToInsertInto] = StringToInsert;
            for (int i = PositionToInsertInto + 1; i < SortedList.Length; i++)
            {
                if (HoldingLocationTwo != null)
                    HoldingLocationOne = HoldingLocationTwo;
                HoldingLocationTwo = SortedList[i];
                SortedList[i] = HoldingLocationOne;
                if (i != SortedList.Length - 1)
                    HoldingLocationOne = SortedList[i + 1];
            }
        }

        public static int GetVoteNumber(string SongEntry)
        {
            return Convert.ToInt32(SongEntry.Substring(SongEntry.LastIndexOf(':') + 1).Replace('\r', ' '));
        }
    }

This works by loading all the strings into one array, and then one by one loading them into the final array, by extracting the vote number and then comparing it to the current array entry. If the votes is higher the entry is put there and the rest of the array is pushed down one. If it is below the value the loop looks at the next entry in the array.

It does not currently handle matching scores because the OP has no stated how this would be done.

The Arrays class has a static method called sort which exists in many overloaded versions so you can pass in an array of any primitive type, or pass in an array of Strings or other Objects.
Since it is the reference of the array that is passed to the sort method nothing needs to be returned from it, the array is altered through the reference.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.