0

First of all I would like to apologize for the code ( I am still learning) I am doing a windows form project with Visual Studio about a Airlinelane seat manager system and I have reached an impasse. Now, the problem is that I have an array of objects called [totSeats] which has been generated with a for loop adding a letter and a number together. What I want to achieve is that when I press the button "Sort by seat" So far I have tried all the conventional method for sorting in C# and also the The Alphanum Algorithm DaveKoelle but it does not work. Here is the Class where all the "logic happens" [EDIT] Someone pointed out about this post How to Sort this String in Ascending Alphanumeric But it is not working as I said I have tried lots of solutions but nothing seems to work. I don't have an output because the compiler generate this error when I tried to implement the solution on the overmentioned method " Cannot convert lambda expression to type array because is not a delegate type".

Now for the output the list needs to basically sort back again as it was originally(1A 2A 3A) ETC..

So by clicking the sort by name the list is rearranged by sorting the list by name, then if I click the sort by seat it needs to go back as it was originally following the order 1A 2A 3A and so on...

I hope this clarify :)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Airline_seat_Reservation
{
public partial class Form1 : Form
{
    static int totalSeats = 200;
    Seat[] totSeats = new Seat[totalSeats];

    string[] firstClassLetter = { "A", "B", "C", "D" };
    string[] econClassLetter = { "A", "B", "C", "D", "E", "F" };
    
    int[] partyEco = { 1, 2, 3 };
    int[] partyFirst = { 1, 2 };

    string[] seatPositionEco = { "Windows", "Middle", "Aisle" };
    string[] seatPositionFirst = { "Windows", "Aisle" };

    // Binding datagrid to array
    private CurrencyManager currencyManager = null;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        int newPosition = 0;
        for (int i = 1; i <= 35; i++)
        {

            if (i <= 5) // specify row for 1st class
            {
                for (int z = 0; z < 4; z++)
                {
                    string[] positionFirst = { "Windows", "Aisle", "Aisle", "Window" };
                    totSeats[newPosition] = new Seat(i + firstClassLetter[z], "First", positionFirst[z]);
                    newPosition++;

                }
            }
            else //specify row for economy class
            {
                for (int v = 0; v < 6; v++)
                {
                    string[] economyPosition = { "Windows", "Middle", "Aisle", "Aisle", "Middle", "Window" };
                    totSeats[newPosition] = new Seat(i + econClassLetter[v], "Economy", economyPosition[v]);
                    newPosition++;
                }
            }
        }
        // Binding datagrid to array
        currencyManager = (CurrencyManager)dataGridView.BindingContext[totSeats];
        dataGridView.DataSource = totSeats;
    }

    //Method for Serialization.
    private void serializeBttn_Click(object sender, EventArgs e)
    {
        Stream stream = File.Open("Passenger.dat", FileMode.Create);
        BinaryFormatter bformatter = new BinaryFormatter();
        bformatter.Serialize(stream, totSeats);
        stream.Close();
        MessageBox.Show("Data Saved to file Thank you!");
    }


    //Method for deserialization.
    private void deserializeBttn_Click(object sender, EventArgs e)
    {
        try
        {
            Stream stream = File.Open("Passenger.dat", FileMode.Open);
            BinaryFormatter bformatter = new BinaryFormatter();

            //Reading Employee Information
            totSeats = (Seat[])bformatter.Deserialize(stream);
            stream.Close();

            currencyManager = (CurrencyManager)dataGridView.BindingContext[totSeats];
            dataGridView.DataSource = totSeats;

            MessageBox.Show("Data Loaded from File");
            dataGridView.Refresh();
        }
        catch (Exception ex)
        { MessageBox.Show(ex.Message, "ERROR reading file!"); }
    }

    private void exitBttn_Click(object sender, EventArgs e)
    {
        Application.Exit();
    }

    private void sortPassenger_Click(object sender, EventArgs e)
    {
        try
        {

            Array.Sort(totSeats);
            dataGridView.DataSource = null;
            dataGridView.DataSource = totSeats;
        }
        catch (Exception u)
        {
            MessageBox.Show(u.Message, "List is empty, Nothing to sort");
        }
    }

    private void sortSeat_Click(object sender, EventArgs e)
    {
        
    }

    private void radioFirstClass_CheckedChanged(object sender, EventArgs e)
    {
        if (this.radioFirstClass.Checked)
        {
            
            comboPeople.DataSource = partyFirst;             
            comboSeat.DataSource = seatPositionFirst;
        }
    }

    private void radioEconomyClass_CheckedChanged(object sender, EventArgs e)
    {
            
            comboPeople.DataSource = partyEco;            
            comboSeat.DataSource = seatPositionEco;
    }

    private void reserveButton_Click(object sender, EventArgs e)
    {
        String comboValue = comboSeat.Text;
        System.Diagnostics.Debug.WriteLine(comboValue);
        

    }
}

This is the class:

[EDITED]

    public class SeatComparer : IComparer
    {
    

          public int Compare(object s1, object s2)
    {
        Seat temp = (Seat)s1;
        Seat temp2 = (Seat)s2;
        string pattern = "([0-9]+)([A-Za-z])";
        string h1 = Regex.Match(temp.SeatNum, pattern).Groups[2].Value;
        string h2 = Regex.Match(temp2.SeatNum, pattern).Groups[2].Value;
        if (h1 != h2)
            return h1.CompareTo(h2);
        string t1 = Regex.Match(temp.SeatNum, pattern).Groups[1].Value;
        string t2 = Regex.Match(temp2.SeatNum, pattern).Groups[1].Value;
        return int.Parse(t1).CompareTo(int.Parse(t2));
    }
}

I have tried everything i Know and researched a lot on the internet before asking here. I really do hope that someone can help me solve this deadlock! Thank you!

UPDATE! I am posting a different solution to sort which works and hopefully will help anyone which had or will have the same problem. This method will replace letters with number, then it will sort them and then the number is back replaced with the original letter previously removed.

private void Replace(Seat x)
    {
        x.SeatNum = x.SeatNum.Replace('A', '1');
        x.SeatNum = x.SeatNum.Replace('B', '2');
        x.SeatNum = x.SeatNum.Replace('C', '3');
        x.SeatNum = x.SeatNum.Replace('D', '4');
        x.SeatNum = x.SeatNum.Replace('E', '5');
        x.SeatNum = x.SeatNum.Replace('F', '6');
    }

    private void sortBySeatBtn_Click(object sender, EventArgs e)
    {
        //Replace every SeatNum with a number
        foreach (object o in aSeat)
        {
            Replace(((Seat)o));
        }

        Array.Sort(aSeat, Seat.sortBySeatID());//use sort method from Seat class

        foreach (object o in aSeat)
        {
            string temp = ((Seat)o).SeatNum.Substring(0, ((Seat)o).SeatNum.Length - 1); // return all minus last digit
            string last = ((Seat)o).SeatNum.Substring(((Seat)o).SeatNum.Length - 1); // return last digit used to compare
            ((Seat)o).SeatNum = temp; //assign temp to current seatNum
            if (last == "1") // is last letter removed equal to 1
            {
                ((Seat)o).SeatNum += "A"; //replace to originary A
            }

            if (last == "2")
            {
                ((Seat)o).SeatNum += "B";
            }

            if (last == "3")
            {
                ((Seat)o).SeatNum += "C";
            }

            if (last == "4")
            {
                ((Seat)o).SeatNum += "D";
            }

            if (last == "5")
            {
                ((Seat)o).SeatNum += "E";
            }

            if (last == "6")
            {
                ((Seat)o).SeatNum += "F";
            }

        }

        dataGridView1.DataSource = null;
        dataGridView1.DataSource = aSeat;

    }
Mafia
  • 1
  • 2
  • In your code, youre sorting the array by PassengerName (see your `CompareTo` method) – adjan Nov 23 '20 at 14:57
  • Hi, please add to your post: 1) this is what I expect as output: `yourExample` and 2) this is what I get as output: `yourActualOutput` – Mong Zhu Nov 23 '20 at 14:57
  • I think [this post](https://stackoverflow.com/questions/17270045/how-to-sort-this-string-in-ascending-alphanumeric) would be a fitting duplicate – Mong Zhu Nov 23 '20 at 15:16
  • Hello! Mong. It is not, because as I said all the solution that I have tried so far are not working. – Mafia Nov 23 '20 at 15:51
  • Adjan, thank you for your response, and yes I am sorting by passenger name but also i need to sort by seat id. – Mafia Nov 23 '20 at 15:52
  • ok, then please explain to us the expected output and the real output. I can consider to reopen the question again. May be I musunderstood your goal. But If I can manage to use the code from the duplicate to solve your problem, I will leave it closed – Mong Zhu Nov 23 '20 at 15:55
  • I am quite confident, that if you write your own `IComparer` like this: `public class SeatComparer : IComparer`, take the solution from the duplicate and change it according to your input: like 1) switch the pattern to `string pattern = "([0-9]+)([A-Za-z])";` and then 2) switch the indices of the groups to handle first `string h1 = Regex.Match(s1.Seat_Num, pattern).Groups[2].Value;` and then `string t1 = Regex.Match(s1.Seat_Num, pattern).Groups[1].Value;` it will produce the order `1A, 2A,...10A,...1B,2B...10B, 11B... ` – Mong Zhu Nov 23 '20 at 16:03
  • 1
    I will try it now! Just give me a couple of min and I'll let you know! – Mafia Nov 23 '20 at 16:06
  • I can't make it work. Do you mind help me further? – Mafia Nov 23 '20 at 16:50
  • What have you done so far? Where exactly is your problem adjusting the duplicate solution to your problem? – Mong Zhu Nov 23 '20 at 18:13
  • So I have tried to create seatComparer class as you suggested inside the seat class When I change and adjust according to my input it simply does not get the array because is in the Form1 class. I have tried to do it in a different class and is not working either. I am not grasping the concept entirely – Mafia Nov 23 '20 at 18:48
  • please post your `seatComparer` class. This is meant to inplement `IComparer` it will have a `CompareTo` method in it that takes 2 objects and compares them like described in the duplicate. You use this class when sorting your array! in this line: `Array.Sort(totSeats);` you would pass it like this: `Array.Sort(totSeats, new SeatComparer());` – Mong Zhu Nov 24 '20 at 07:36
  • I have tried so far to implement the class but Seat_Num is highlighted in red with this error: "CS1061: 'object' does not contain a definition for SeatNum and no accessible extension method 'SeatNum' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)" This is the class : – Mafia Nov 24 '20 at 23:34
  • I have edited the class in the original post. I declared in the class Seat_Num but the error is still there. And i also tried to implementing it on the seat class itself as the variable is present there but it gives me the same error – Mafia Nov 24 '20 at 23:38
  • you are almost there. 1) the `SeatComparer : IComparer` class is actually independent of the `Seat` class that will be sorted. So you don't need any properties in there. You need to cast the objects `s1` and `s2` to a `Seat` in the method `public int Compare(object s1, object s2)`. 2) the indices are not correct yet when accessing the groups from your regex match. `string h2 = Regex.Match(s2.SeatNum, pattern).Groups[1].Value;` needs also to be the second group! like in s1. 3) you need to pass a `SeatComparer` instance into the sort method like this: `Array.Sort(totSeats, new SeatComparer);` – Mong Zhu Nov 25 '20 at 10:12
  • I have updated the class on the post but when I run it, the way you explained it gives me this exception on this line return int.Parse(t1).CompareTo(int.Parse(t2)); input string was not in a correct format – Mafia Nov 25 '20 at 11:32
  • because the groups that you match have to be equal. t1 and t2. Group 2 means that it will contain the match `([A-Za-z])` and group 1 means that it will contain the numbers. you need to take the match of the numbers if you are parsing it to int: `string t2 = Regex.Match(temp2.SeatNum, pattern).Groups[1].Value;` – Mong Zhu Nov 25 '20 at 12:25
  • I have tried as you said but even in that way it sort 1A, 2B, 3C, 4D, but it should be 1A, 1B, 1C, 1D, 2A, 2B, etc ... so i have implemented a different solution which is in the update up above and hopefully will help someone who had my same issue. Thank you for your help. I really appreciate it! – Mafia Nov 25 '20 at 13:54
  • "but it should be 1A, 1B, 1C, 1D, 2A, 2B, etc ..." hey mate, I asked you for this in the second comment of mine, 2 days ago. This is a vital information! next time, please try to provide such information in your post. To achieve this you only need to swap the comparisons. Have the numbers be compared first and then the letters and you will get the desired result. You should play a little more with code that you find on StackOverflow. It helps to get a better understanding of the workings of the code, which in turn makes you capable of adopting it to your own needs. Happy coding mate – Mong Zhu Nov 25 '20 at 15:43

0 Answers0