Results 1 to 21 of 21

Thread: Does Simba have dictionary/hash datatype?

  1. #1
    Join Date
    Feb 2006
    Location
    Tracy/Davis, California
    Posts
    12,631
    Mentioned
    135 Post(s)
    Quoted
    418 Post(s)

    Default Does Simba have dictionary/hash datatype?

    Does Simba have a dictionary/hash datatype, or anything similar?


    Happy Holidays

    E: Seems like no, unless you make your own
    https://villavu.com/forum/showthread.php?t=76370
    Last edited by YoHoJo; 12-22-2016 at 04:00 AM.

  2. #2
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default

    What do you mean like a Hashtable or encryption functions?

  3. #3
    Join Date
    Feb 2006
    Location
    Tracy/Davis, California
    Posts
    12,631
    Mentioned
    135 Post(s)
    Quoted
    418 Post(s)

    Default

    @rj
    I mean like a a hashmap. Collection of key,value pairs.
    Like an array, but with self-defined string as indexes.

  4. #4
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default

    Quote Originally Posted by YoHoJo View Post
    @rj
    I mean like a a hashmap. Collection of key,value pairs.
    Like an array, but with self-defined string as indexes.
    Couldn't find anything related to 'hashtable' (var type would probs be called THashTable) soo

    it does not seem to have it, i looked at the source and everything with the keyword 'hash' seemed to be related to encryption though I could have missed something

    https://github.com/MerlijnWajer/Simb...2%9C%93&q=hash

  5. #5
    Join Date
    Feb 2006
    Location
    Tracy/Davis, California
    Posts
    12,631
    Mentioned
    135 Post(s)
    Quoted
    418 Post(s)

    Default

    Quote Originally Posted by rj View Post
    Couldn't find anything related to 'hashtable' (var type would probs be called THashTable) soo

    it does not seem to have it, i looked at the source and everything with the keyword 'hash' seemed to be related to encryption though I could have missed something

    https://github.com/MerlijnWajer/Simb...2%9C%93&q=hash
    Thanks for checking it out rj!
    "You must spread some Reputation around before giving it to rj again."
    I'll live without, would just be convenient.

    I linked a thread in OP with someone else wondering the same.

  6. #6
    Join Date
    Nov 2011
    Location
    England
    Posts
    3,072
    Mentioned
    296 Post(s)
    Quoted
    1094 Post(s)

    Default

    Closest you're gonna get built in is a TStringList, it's doesn't hash so it's not very efficient compared to a hashmap but still works well for simple things.

    Simba Code:
    var
      List: TStringList;

    begin
      List.Init();

      List.setValues('key', 'hello world!');
      Writeln(list.getValues('key'));

      List.Free();
    end.
    Last edited by Olly; 12-22-2016 at 04:38 AM.

  7. #7
    Join Date
    Jan 2012
    Posts
    2,568
    Mentioned
    35 Post(s)
    Quoted
    356 Post(s)

    Default

    What's the data type of your key and the range?

    If your keys are integers of small range, you can use arrays to simulate it. If they are larger size than your memory constraint, or if they are strings etc, you can use some hash functions to map to the indexes of the array (using an appropriate collision resolution scheme).

  8. #8
    Join Date
    Feb 2006
    Location
    Tracy/Davis, California
    Posts
    12,631
    Mentioned
    135 Post(s)
    Quoted
    418 Post(s)

    Default

    Quote Originally Posted by Olly View Post
    Closest you're gonna get built in is a TStringList, it's doesn't hash so it's not very efficient compared to a hashmap but still works well for simple things.

    Simba Code:
    var
      List: TStringList;

    begin
      List.Init();

      List.setValues('key', 'hello world!');
      Writeln(list.getValues('key'));

      List.Free();
    end.
    This will be useful! I assume the value has to be a string?
    First time hearing about TStringList, thanks.
    I think I'll be able to whip up something I like with this.

    Quote Originally Posted by riwu View Post
    What's the data type of your key and the range?

    If your keys are integers of small range, you can use arrays to simulate it. If they are larger size than your memory constraint, or if they are strings etc, you can use some hash functions to map to the indexes of the array (using an appropriate collision resolution scheme).
    Keys can be strings, values will be doubles and strings.

    Ex:
    Currently I have either:
    Simba Code:
    ['1482379301.9522', 'yeet', '9.6'] //TStringArray
    [1482379301.9522, 'yeet', 9.60]  // TVariantArray

    Instead of having to call a value by it's index, I want call it by a name.
    Simba Code:
    imaginary_struct := ['big_number'   => 1482379301.9522,
                         'word'         => "yeet",
                         'small_number' => 9.60;
                        ]
    imaginary_struct['big_number'];// 1482379301.9522
    //or
    imaginary_struct.big_number;// 1482379301.9522
    Last edited by YoHoJo; 12-22-2016 at 05:50 AM.

  9. #9
    Join Date
    Jan 2012
    Posts
    2,568
    Mentioned
    35 Post(s)
    Quoted
    356 Post(s)

    Default

    So the your objective is just to call a value by name rather than index? For your second call, big_number must be a field of the struct record? Is ur data size small enough that even linear search suffice?

  10. #10
    Join Date
    Feb 2006
    Location
    Tracy/Davis, California
    Posts
    12,631
    Mentioned
    135 Post(s)
    Quoted
    418 Post(s)

    Default

    Quote Originally Posted by riwu View Post
    So the your objective is just to call a value by name rather than index?
    Yup

    For your second call, big_number must be a field of the struct record?
    Field as in key? Sure, otherwise it'd return error or nil or whatever.

    Is ur data size small enough that even linear search suffice?
    Yeah it's small.


    ing something up?
    Last edited by YoHoJo; 12-22-2016 at 06:25 AM.

  11. #11
    Join Date
    Jan 2012
    Posts
    2,568
    Mentioned
    35 Post(s)
    Quoted
    356 Post(s)

    Default

    I still don't quite get what you need. Are these keys (big_number, word etc) known at compile time? If not how are they retrieved/determined at run time?

  12. #12
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default

    why do i need thinking this threads in nota?

  13. #13
    Join Date
    Feb 2006
    Location
    Tracy/Davis, California
    Posts
    12,631
    Mentioned
    135 Post(s)
    Quoted
    418 Post(s)

    Default

    In my case, the keys will be hardcoded, values will be returned by a function.

  14. #14
    Join Date
    Jan 2012
    Posts
    2,568
    Mentioned
    35 Post(s)
    Quoted
    356 Post(s)

    Default

    Quote Originally Posted by YoHoJo View Post
    In my case, the keys will be hardcoded, values will be returned by a function.
    Wouldn't using a record be most appropriate then? Declare the imaginary_struct as a record with the keys as the fields?

  15. #15
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default

    Quote Originally Posted by YoHoJo View Post
    In my case, the keys will be hardcoded, values will be returned by a function.
    so couldn't you just keep them all in a file

    Code:
    big_number|1482379301.9522
    word|yeet
    small_number|9.60

    Then have each line in the file returned with a string length of 2. then you can do the searching them there


    Simba Code:
    type twhatever = array[0..1] of string;

    twhateverarray = array of twhatever;


    function getFileContents():twhateverarray;
    var
      fileshit:string;
      t, r:tstringarray;
      i:integer;
    begin
      // blah blah read file stuff
      //readFileString(f, fileShit, fileSize(f));

      {
      big_number|1482379301.9522
      word|yeet
      small_number|9.60

      some lines function forget parameters
      what will give you a tsa of the example string like
      t = {big_number|1482379301.9522, word|yeet, small_number|9.60}


      //t := lines(fileshit, #0#10);

      t := ['big_number|1482379301.9522',
      'word|yeet','small_number|9.60'];


      setLength(result, length(t));

      for i := 0 to high(t) do
      begin
        r := explode('|', t[i]);
        result[i][0] := r[0];
        result[i][1] := r[1];
      end;

      // this function is dangerous if you dont store the values right.
    end;


    begin
      writeln(getFileContents());
    end.

    result

    Code:
    Compiled successfully in 297 ms.
    [[big_number, 1482379301.9522], [word, yeet], [small_number, 9.60]]
    Successfully executed.

  16. #16
    Join Date
    Feb 2006
    Location
    Tracy/Davis, California
    Posts
    12,631
    Mentioned
    135 Post(s)
    Quoted
    418 Post(s)

    Default

    Quote Originally Posted by riwu View Post
    Wouldn't using a record be most appropriate then? Declare the imaginary_struct as a record with the keys as the fields?
    Works great ! til, records.

    Thanks for tuts
    @The Mayorhttps://villavu.com/forum/showthread.php?t=113227
    @Broteinhttps://villavu.com/forum/showthread.php?t=113918

  17. #17
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Not sure why Simba doesn't have this built in. Also would be nice if Simba had generics but meh.. one can only dream.



    Anyway, I wrote one.. @YoHoJo;


    Interface:
    Simba Code:
    procedure THashMap.Init(hasher: function(key: String): UInt32);
    procedure THashMap.Destroy();

    function THashMap.get(key: String): ^String;
    procedure THashMap.put(key: String; value: String);

    function THashMap.bucketSize(): UInt32;
    function THashMap.size(): UInt32;

    function StringHash(str: String): UInt32;
    function ObjectHash(object: TObject): UInt32;


    Usage:
    Simba Code:
    var
      map: THashMap;
    begin
      map.Init(@StringHash);

      map.put('A', '100');
      map.put('B', '200');
      map.put('C', '300');
      map.put('D', '400');
      map.put('E', '500');
      map.put('F', '600');
      map.put('G', '700');
      map.put('H', '800');
      map.put('I', '900');
      map.put('J', '1000');
      map.put('K', '1100');
      map.put('L', '1200');
      map.put('M', '1300');
      map.put('N', '1400');
      map.put('O', '1500');
      map.put('P', '1600');
      map.put('Q', '1700');
      map.put('R', '1800');
      map.put('S', '1900');
      map.put('T', '2000');
      map.put('U', '2100');
      map.put('V', '2200');
      map.put('W', '2300');
      map.put('X', '2400');
      map.put('Y', '2500');
      map.put('Z', '2600');

      writeln(map.get('B')^);

      map.Destroy();
    end.


    Implementation:
    Simba Code:
    type

      PEntry = ^TEntry;
      TEntry = record
        Key: String;
        Value: String;
        Next: PEntry;
      end;

      THashMap = record
        __loadfactor: Single;
        __threshold: UInt32;
        __size: UInt32;
        __hash: function(key: String): UInt32;
        __entries: array of PEntry;
      end;

    procedure THashMap.Init(hasher: function(key: String): UInt32);
    begin
      self.Destroy();
      __loadfactor := 0.75;
      __threshold := UInt32((1 shl 4) * __loadfactor);
      __size := 0;
      __hash := @hasher;
      SetLength(__entries, 1 shl 4);
    end;

    procedure THashMap.Destroy();
    var
      i: Integer;
      oldEntry: PEntry;
      entry: PEntry;
    begin
      for i := 0 to high(__entries) do
      begin
        entry := __entries[i];

        while(entry <> nil) do
        begin
          oldEntry := entry;
          entry := entry^.next;
          FreeMem(entry);
        end;
      end;
    end;

    function THashMap.get(key: String): ^String;
    var
      index: UInt32;
      entry: PEntry;
    begin
      index := __hash(key) mod Length(__entries);

      if (__entries[index] = nil) then
        exit(nil);

      entry := __entries[index];

      while(entry <> nil) do
      begin
        if (entry^.key = key) then
          exit(@entry^.value);

        entry := entry^.next;
      end;

      exit(nil);
    end;

    procedure THashMap.put(key: String; value: String);
    var
      index: UInt32;
      entry: PEntry;
    begin
      index := __hash(key) mod Length(__entries);
      entry := __entries[index];


      if (entry = nil) then
      begin
        entry := AllocMem(sizeof(TEntry));
        entry^.key := key;
        entry^.value := value;
        entry^.next := nil;
        __entries[index] := entry;
        inc(__size);
      end else
        begin
          while(entry^.next <> nil) do
            entry := entry^.next;

          if (entry^.key = key) then
          begin
            entry^.value := value;
          end else
            begin
              entry := AllocMem(sizeof(TEntry));
              entry^.key := key;
              entry^.value := value;
              entry^.next := nil;
              __entries[index] := entry;
              inc(__size);
            end;
        end;

        if (__size >= __threshold) then
          self.__resize();
    end;

    function THashMap.bucketSize(): UInt32;
    begin
      result := Length(__entries);
    end;

    function THashMap.size(): UInt32;
    begin
      result := __size;
    end;

    procedure THashMap.__resize();
    var
      i: Integer;
      oldEntry: PEntry;
      entry: PEntry;
      oldEntries: array of PEntry;
    begin
      oldEntries := __entries;
      __entries := [];
      SetLength(__entries, Length(oldEntries) * 2);

      __size := 0;
      __threshold := UInt32(Length(__entries) * __loadfactor);

      for i := 0 to high(oldEntries) do
      begin
        entry := oldEntries[i];

        while(entry <> nil) do
        begin
          self.put(entry^.key, entry^.value);

          oldEntry := entry;
          entry := entry^.next;
          FreeMem(oldEntry);
        end;
      end;
    end;



    function StringHash(self: String): UInt32;
    var
      hash: UInt32;
      i: Integer;
    begin
      hash := 0;

      if (Length(self) > 0) then
        for i := 1 to Length(self) do
          hash := 37 * hash + Ord(self[i]);

      exit(hash);
    end;

    function ObjectHash(self: TObject): UInt32;
    var
      hash: UInt32;
      ptr: Pointer;
      i: Integer;
    begin
      ptr := @self;

      for i := 0 to sizeof(self) do
      begin
        hash := 37 * hash + Integer(ptr^ + 1);
        inc(ptr);
      end;

      exit(hash);
    end;
    I am Ggzz..
    Hackintosher

  18. #18
    Join Date
    Apr 2012
    Posts
    34
    Mentioned
    0 Post(s)
    Quoted
    20 Post(s)

    Default

    Tf are you guys even talking about. Someone break it down for a noob



  19. #19
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Quote Originally Posted by Leafy View Post
    Tf are you guys even talking about. Someone break it down for a noob

    Instead of posting on every thread to gain post count, try googling what a Hash Table is. I'm sure you can do that.


    https://en.wikipedia.org/wiki/Hash_table
    I am Ggzz..
    Hackintosher

  20. #20
    Join Date
    Apr 2012
    Posts
    34
    Mentioned
    0 Post(s)
    Quoted
    20 Post(s)

    Default

    Quote Originally Posted by Brandon View Post
    Instead of posting on every thread to gain post count, try googling what a Hash Table is. I'm sure you can do that.


    https://en.wikipedia.org/wiki/Hash_table
    M8, my life depends on post counts.



  21. #21
    Join Date
    Sep 2010
    Posts
    5,762
    Mentioned
    136 Post(s)
    Quoted
    2739 Post(s)

    Default

    Quote Originally Posted by Leafy View Post
    M8, my life depends on post counts.
    Addicted to post counts been there

    I kicked my rep habbit and moved on to quotes. From there it just got worse whoring quotes and posts. Eventually a new thing came out called 'mentions', hadn't really been used by many people. "mentions are the new rep" sin - 2013. At rock bottom I was slamming quotes, rep and mentions anyway I could

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •