How can I sort a HashTable by a specified column?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Oberon

    How can I sort a HashTable by a specified column?

    My HashTable (Global.Games) is a static collection of objects of type
    Game. A Game object has 8 fields (exposed as properties). The key to
    the HashTable is also one of these fields (GameID, of type int).

    When I try to create a SortedList from the HashTable with the
    following:

    SortedList sortedGames = new SortedList(Glob al.Games);

    I get an error message:

    Argument '1': cannot convert from 'ChatMark1.Game HashTable' to 'int'

    But the SortedList constructor is overloaded and one parameter it
    accepts is an object of type Systems.Collect ion.IDictionary . Why does
    it now expect the Global.Games to be of type 'int'?

  • Jon Skeet [C# MVP]

    #2
    Re: How can I sort a HashTable by a specified column?

    Oberon <Oberon@solstic e.com> wrote:[color=blue]
    > My HashTable (Global.Games) is a static collection of objects of type
    > Game. A Game object has 8 fields (exposed as properties). The key to
    > the HashTable is also one of these fields (GameID, of type int).
    >
    > When I try to create a SortedList from the HashTable with the
    > following:
    >
    > SortedList sortedGames = new SortedList(Glob al.Games);
    >
    > I get an error message:
    >
    > Argument '1': cannot convert from 'ChatMark1.Game HashTable' to 'int'
    >
    > But the SortedList constructor is overloaded and one parameter it
    > accepts is an object of type Systems.Collect ion.IDictionary . Why does
    > it now expect the Global.Games to be of type 'int'?[/color]

    Could you post a short but complete program which demonstrates the
    problem?

    See http://www.pobox.com/~skeet/csharp/complete.html for details of
    what I mean by that.

    --
    Jon Skeet - <skeet@pobox.co m>
    Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

    If replying to the group, please do not mail me too

    Comment

    • Jon Skeet [C# MVP]

      #3
      Re: How can I sort a HashTable by a specified column?

      Oberon <Oberon@solstic e.com> wrote:[color=blue]
      > My HashTable (Global.Games) is a static collection of objects of type
      > Game. A Game object has 8 fields (exposed as properties). The key to
      > the HashTable is also one of these fields (GameID, of type int).
      >
      > When I try to create a SortedList from the HashTable with the
      > following:
      >
      > SortedList sortedGames = new SortedList(Glob al.Games);
      >
      > I get an error message:
      >
      > Argument '1': cannot convert from 'ChatMark1.Game HashTable' to 'int'
      >
      > But the SortedList constructor is overloaded and one parameter it
      > accepts is an object of type Systems.Collect ion.IDictionary . Why does
      > it now expect the Global.Games to be of type 'int'?[/color]

      Could you post a short but complete program which demonstrates the
      problem?

      See http://www.pobox.com/~skeet/csharp/complete.html for details of
      what I mean by that.

      --
      Jon Skeet - <skeet@pobox.co m>
      Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

      If replying to the group, please do not mail me too

      Comment

      • Oberon

        #4
        Re: How can I sort a HashTable by a specified column?

        On Fri, 20 May 2005 06:50:33 +0100, Jon Skeet [C# MVP]
        <skeet@pobox.co m> wrote:
        [color=blue]
        >Oberon <Oberon@solstic e.com> wrote:[color=green]
        >> My HashTable (Global.Games) is a static collection of objects of type
        >> Game. A Game object has 8 fields (exposed as properties). The key to
        >> the HashTable is also one of these fields (GameID, of type int).
        >>
        >> When I try to create a SortedList from the HashTable with the
        >> following:
        >>
        >> SortedList sortedGames = new SortedList(Glob al.Games);
        >>
        >> I get an error message:
        >>
        >> Argument '1': cannot convert from 'ChatMark1.Game HashTable' to 'int'
        >>
        >> But the SortedList constructor is overloaded and one parameter it
        >> accepts is an object of type Systems.Collect ion.IDictionary . Why does
        >> it now expect the Global.Games to be of type 'int'?[/color]
        >
        >Could you post a short but complete program which demonstrates the
        >problem?
        >
        >See http://www.pobox.com/~skeet/csharp/complete.html for details of
        >what I mean by that.[/color]

        I can't do that. I have to post two complete pages. This is the
        'simplified' code for the problem, below.

        The program fails on this line:

        SortedList sortedGames = new SortedList(Glob al.Games);

        with the error messages:

        Argument '1': cannot convert from 'SortHash.GameH ashTable' to
        'int'
        The best overloaded method match for
        'System.Collect ions.SortedList .SortedList(int )' has some invalid
        arguments
        Could not find any attribute 'disabled' of element 'CheckBox'.

        (The 3rd (other) error message is not important since the program
        works even if the offending disabled attribute is left in the code
        when the line creating the SortedList is commentated out.

        I can see what I'm doing wrong now. I'm giving the wrong parameters to
        the new SortedList. The problem is that I don't actually understand
        what parameters it will take here. I was using an example from some
        book code, but perhaps the constructors for the sorted list have
        changed since then?, or maybe the code only works with a simple
        HashTable, not my more complex one?

        Would I be better off leaving the HashTable out completely and just
        putting my recordset in the Application Cache? I think so. That is
        what I will try to do to solve the problem as I'm probably out of my
        depth here.


        + + + + + + + + + + + + + + + + + + + + +
        Here is my web page.
        + + + + + + + + + + + + + + + + + + + + +
        <%@ Page language="c#" Codebehind="Def ault.aspx.cs"
        AutoEventWireup ="false" Inherits="SortH ash._Default1" %>
        <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
        <HTML>
        <HEAD>
        <title>Defaul t</title>
        <meta content="Micros oft Visual Studio .NET 7.1" name="GENERATOR ">
        <meta content="C#" name="CODE_LANG UAGE">
        <meta content="JavaSc ript" name="vs_defaul tClientScript">
        <meta content="http://schemas.microso ft.com/intellisense/ie5"
        name="vs_target Schema">
        </HEAD>
        <body>
        <form id="Form1" method="post" runat="server">
        <asp:DataGrid id="dgGames" runat="server"
        AutoGenerateCol umns="False" EnableViewState ="False"
        AllowSorting="T rue" OnSortCommand=" SortRows">
        <Columns>
        <asp:BoundColum n DataField="Titl e" HeaderText="Tit le"
        SortExpression= "Title"></asp:BoundColumn >
        <asp:BoundColum n DataField="Play Time" HeaderText="Day "
        DataFormatStrin g="{0:ddd}"></asp:BoundColumn >
        <asp:BoundColum n DataField="Play Time" HeaderText="Tim e"
        DataFormatStrin g="{0:HH':'mm': ' 'GMT'}"></asp:BoundColumn >
        <asp:BoundColum n DataField="Play Time" HeaderText="Sta rt"
        SortExpression= "Start" DataFormatStrin g="{0:m}"></asp:BoundColumn >
        <asp:TemplateCo lumn HeaderText="Rec ruiting">
        <ItemTemplate >
        <asp:CheckBox id="chkRecruiti ng" runat="server"
        Checked='<%# DataBinder.Eval (Container, "DataItem.Recru iting") %>'
        disabled />
        </ItemTemplate>
        </asp:TemplateCol umn>
        </Columns>
        </asp:DataGrid></form>
        </body>
        </HTML>

        + + + + + + + + + + + + + + + + + + + + +
        Here is the code behind for the above page:
        + + + + + + + + + + + + + + + + + + + + +

        using System;
        using System.Collecti ons;
        using System.Componen tModel;
        using System.Data;
        using System.Drawing;
        using System.Web;
        using System.Web.Sess ionState;
        using System.Web.UI;
        using System.Web.UI.W ebControls;
        using System.Web.UI.H tmlControls;

        namespace SortHash
        {
        public class _Default1 : System.Web.UI.P age
        {
        protected System.Web.UI.W ebControls.Data Grid dgGames;

        private void Page_Load(objec t sender, System.EventArg s e)
        {
        dgGames.DataSou rce = Global.Games;
        dgGames.DataBin d();
        }

        public void SortRows(object sender, DataGridSortCom mandEventArgs
        e)
        {
        SortedList sortedGames = new SortedList(Glob al.Games);
        dgGames.DataSou rce = Global.Games;
        dgGames.DataBin d();
        }

        #region Web Form Designer generated code
        override protected void OnInit(EventArg s e)
        {
        InitializeCompo nent();
        base.OnInit(e);
        }

        private void InitializeCompo nent()
        {
        this.Load += new System.EventHan dler(this.Page_ Load);

        }
        #endregion
        }
        public class GameHashTable : IEnumerable
        {
        Hashtable _games;

        public GameHashTable()
        {
        _games = new Hashtable();
        }
        public IEnumerator GetEnumerator()
        {
        return _games.Values.G etEnumerator();
        }
        public Game this[int GameID]
        {
        get {return (Game) _games[GameID];}
        set {Add(value);}
        }
        public void Add(Game Item)
        {
        if (Item == null)
        throw new ArgumentExcepti on("Game can not be null");
        _games.Add(Item .GameID, Item);

        }
        public void Remove(Game Item)
        {
        _games.Remove(I tem.GameID);
        }
        }

        public class Game
        {
        private int _gameID;
        private string _title;
        private bool _recruiting;
        private DateTime _playTime;

        public Game(
        int initialGameID,
        string initialTitle,
        bool initialRecruiti ng,
        DateTime initialPlayTime )
        {
        GameID = initialGameID;
        Title = initialTitle;
        Recruiting = initialRecruiti ng;
        PlayTime = initialPlayTime ;
        }

        public int GameID
        {
        get { return _gameID; }
        set {_gameID = value;}
        }
        public string Title
        {
        get {return _title;}
        set {_title = value;}
        }
        public bool Recruiting
        {
        get {return _recruiting;}
        set {_recruiting = value;}
        }
        public DateTime PlayTime
        {
        get {return _playTime;}
        set {_playTime = value;}
        }
        }
        }


        + + + + + + + + + + + + + + + + + + + + +
        Here is my Global.asax
        + + + + + + + + + + + + + + + + + + + + +
        using System;
        using System.Collecti ons;
        using System.Componen tModel;
        using System.Data.Sql Client;
        using System.Web;
        using System.Web.Sess ionState;

        namespace SortHash
        {
        public class Global : System.Web.Http Application
        {
        public static string gameConnection = "packet size=4096;user
        id=ape;pwd=monk ey;data source=ASROCK;p ersist security
        info=False;init ial catalog=ChatMar k1";
        public static GameHashTable games;
        private System.Componen tModel.IContain er components = null;

        public Global()
        {
        InitializeCompo nent();
        }

        protected void Application_Sta rt(Object sender, EventArgs e)
        {
        Global.GameLoad ();
        }

        public static string GameConnection
        { get { return gameConnection; } }

        public static void GameLoad()
        {
        SqlConnection connGames = new SqlConnection(g ameConnection);
        connGames.Open( );
        SqlCommand cmd = new SqlCommand("SEL ECT gameID, title,
        recruiting, playTime FROM Games", connGames);
        SqlDataReader reader;
        reader = cmd.ExecuteRead er();

        Game game;
        games = new GameHashTable() ;
        while (reader.Read())
        {
        game = new Game(
        reader.GetInt32 (0),
        reader.GetStrin g(1),
        reader.GetBoole an(2),
        reader.GetDateT ime(3));
        games.Add(game) ;
        }
        reader.Close();
        connGames.Close ();
        }

        public static GameHashTable Games
        {
        get { return games; }
        }

        #region Web Form Designer generated code
        private void InitializeCompo nent()
        {
        this.components = new System.Componen tModel.Containe r();
        }
        #endregion
        }
        }

        + + + + + + + + + + + + + + + + + + + + +
        Last. My database table:
        + + + + + + + + + + + + + + + + + + + + +

        CREATE TABLE Games (
        gameID int IDENTITY (1, 1) NOT NULL ,
        title varchar (50) NOT NULL ,
        recruiting bit NOT NULL CONSTRAINT DF_Games_recrui ting DEFAULT
        (1),
        playTime datetime NOT NULL CONSTRAINT DF_Games_playTi me DEFAULT
        (getdate()),
        CONSTRAINT PK_Games PRIMARY KEY CLUSTERED (gameID) ON PRIMARY
        )

        Comment

        • Jon Skeet [C# MVP]

          #5
          Re: How can I sort a HashTable by a specified column?

          Oberon <Oberon@solstic e.com> wrote:[color=blue][color=green]
          > >See http://www.pobox.com/~skeet/csharp/complete.html for details of
          > >what I mean by that.[/color]
          >
          > I can't do that. I have to post two complete pages.[/color]

          No, you don't. Here's a short but complete program which shows exactly
          what's going wrong, without any ASP.NET at all:

          using System;
          using System.Collecti ons;

          public class Test
          {
          static void Main()
          {
          GameHashTable hash = new GameHashTable() ;
          new SortedList(hash );
          }
          }

          public class GameHashTable : IEnumerable
          {
          public IEnumerator GetEnumerator()
          {
          return null;
          }
          }

          The problem is that your GameHashTable isn't an IDictionary, so it
          certainly can't use the SortedList(IDic tionary) constructor.
          [color=blue]
          > I can see what I'm doing wrong now. I'm giving the wrong parameters to
          > the new SortedList. The problem is that I don't actually understand
          > what parameters it will take here.[/color]

          Exactly the documented ones.
          [color=blue]
          > I was using an example from some
          > book code, but perhaps the constructors for the sorted list have
          > changed since then?, or maybe the code only works with a simple
          > HashTable, not my more complex one?[/color]

          No, it works with anything which implements IDictionary - which your
          class doesn't.

          --
          Jon Skeet - <skeet@pobox.co m>
          Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

          If replying to the group, please do not mail me too

          Comment

          • Oberon

            #6
            Re: How can I sort a HashTable by a specified column?

            On Fri, 20 May 2005 17:41:12 +0100, Jon Skeet [C# MVP]
            <skeet@pobox.co m> wrote:
            [color=blue]
            >Oberon <Oberon@solstic e.com> wrote:[color=green][color=darkred]
            >> >See http://www.pobox.com/~skeet/csharp/complete.html for details of
            >> >what I mean by that.[/color]
            >>
            >> I can't do that. I have to post two complete pages.[/color]
            >
            >No, you don't. Here's a short but complete program which shows exactly
            >what's going wrong, without any ASP.NET at all:
            >
            >using System;
            >using System.Collecti ons;
            >
            >public class Test
            >{
            > static void Main()
            > {
            > GameHashTable hash = new GameHashTable() ;
            > new SortedList(hash );
            > }
            >}
            >
            >public class GameHashTable : IEnumerable
            >{
            > public IEnumerator GetEnumerator()
            > {
            > return null;
            > }
            >}
            >
            >The problem is that your GameHashTable isn't an IDictionary, so it
            >certainly can't use the SortedList(IDic tionary) constructor.[/color]

            I've given up on the idea of using a HashTable to do this job and will
            use a DataSet inserted into the Cache instead; which is what 99% of
            people would do when faced with a similar problem to mine.
            [color=blue][color=green]
            >> I can see what I'm doing wrong now. I'm giving the wrong parameters to
            >> the new SortedList. The problem is that I don't actually understand
            >> what parameters it will take here.[/color]
            >
            >Exactly the documented ones.
            >[color=green]
            >> I was using an example from some
            >> book code, but perhaps the constructors for the sorted list have
            >> changed since then?, or maybe the code only works with a simple
            >> HashTable, not my more complex one?[/color]
            >
            >No, it works with anything which implements IDictionary - which your
            >class doesn't.[/color]

            But the documentation says that a HashTable does implement
            IDictionary:

            <http://msdn.microsoft. com/library/default.asp?url =/library/en-us/cpref/html/frlrfsystemcoll ectionshashtabl eclasstopic.asp >

            Comment

            • Wavemaker

              #7
              Re: How can I sort a HashTable by a specified column?


              "Oberon" wrote:[color=blue]
              > On Fri, 20 May 2005 17:41:12 +0100, Jon Skeet [C# MVP]
              > <skeet@pobox.co m> wrote:[/color]

              <snip>
              [color=blue][color=green]
              >>No, it works with anything which implements IDictionary - which your
              >>class doesn't.[/color]
              >
              > But the documentation says that a Hashtable does implement
              > IDictionary:[/color]

              But you're not passing a Hashtable object to a SortedList.

              public class GameHashTable : IEnumerable
              {
              Hashtable _games;

              // ...
              }

              The GameHashTable class contains a Hashtable, but doesn't implement the
              IDictionary interface. It's not the same thing. So when you pass an
              instance of the GameHashTable:

              SortedList sortedGames = new SortedList(Glob al.Games);

              You get an error.

              Global.Games is an instance of the GameHashTable class, not an instance
              of the Hashtable class.



              Comment

              • Jon Skeet [C# MVP]

                #8
                Re: How can I sort a HashTable by a specified column?

                Oberon <Oberon@solstic e.com> wrote:[color=blue][color=green]
                > >The problem is that your GameHashTable isn't an IDictionary, so it
                > >certainly can't use the SortedList(IDic tionary) constructor.[/color]
                >
                > I've given up on the idea of using a HashTable to do this job and will
                > use a DataSet inserted into the Cache instead; which is what 99% of
                > people would do when faced with a similar problem to mine.[/color]

                Well, without knowing more about it, I couldn't say for sure.
                Personally I'd usually prefer a Hashtable to a DataSet just for
                simplicity.
                [color=blue][color=green]
                > >No, it works with anything which implements IDictionary - which your
                > >class doesn't.[/color]
                >
                > But the documentation says that a HashTable does implement
                > IDictionary:[/color]

                Absolutely. And that would be fine if your class derived from
                HashTable, but it doesn't. Here's the declaration of your class:

                public class GameHashTable : IEnumerable

                Nothing about HashTable in there.

                --
                Jon Skeet - <skeet@pobox.co m>
                Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

                If replying to the group, please do not mail me too

                Comment

                • Oberon

                  #9
                  Re: How can I sort a HashTable by a specified column?

                  On Sat, 21 May 2005 10:24:40 +0100, Jon Skeet [C# MVP]
                  <skeet@pobox.co m> wrote:
                  [color=blue]
                  >Oberon <Oberon@solstic e.com> wrote:[color=green][color=darkred]
                  >> >The problem is that your GameHashTable isn't an IDictionary, so it
                  >> >certainly can't use the SortedList(IDic tionary) constructor.[/color]
                  >>
                  >> I've given up on the idea of using a HashTable to do this job and will
                  >> use a DataSet inserted into the Cache instead; which is what 99% of
                  >> people would do when faced with a similar problem to mine.[/color]
                  >
                  >Well, without knowing more about it, I couldn't say for sure.
                  >Personally I'd usually prefer a Hashtable to a DataSet just for
                  >simplicity.
                  >[color=green][color=darkred]
                  >> >No, it works with anything which implements IDictionary - which your
                  >> >class doesn't.[/color]
                  >>
                  >> But the documentation says that a HashTable does implement
                  >> IDictionary:[/color]
                  >
                  >Absolutely. And that would be fine if your class derived from
                  >HashTable, but it doesn't. Here's the declaration of your class:
                  >
                  >public class GameHashTable : IEnumerable
                  >
                  >Nothing about HashTable in there.[/color]

                  Thanks for all that. I see I need to study more. I'll use DataSets
                  until I get the hang of this.

                  Comment

                  • Jon Skeet [C# MVP]

                    #10
                    Re: How can I sort a HashTable by a specified column?

                    Oberon <Oberon@solstic e.com> wrote:[color=blue]
                    > Thanks for all that. I see I need to study more. I'll use DataSets
                    > until I get the hang of this.[/color]

                    I wouldn't - DataSets are more complicated than HashTables, and if
                    you're having trouble understanding the problem, I think you should
                    really look at the language basics again. I always think it's worth
                    spending more time getting the basics right rather than ploughing
                    regardless into more complicated things where you're likely to get
                    stuck.

                    --
                    Jon Skeet - <skeet@pobox.co m>
                    Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.

                    If replying to the group, please do not mail me too

                    Comment

                    Working...