Question

I am trying to add hash to my hash of hashes like this:

  %funkce = (
    "funkce1" => {
      "file" => "soubor1",
      "name" => "jmeno1",
      "varargs" => "args",
      "rettype" => "navrat",
      "params" => [
                "typ",
                "typ2"
            ]
    },
    "funkce2" => {
      "file" => "soubor2",
      "name" => "jmeno2",
      "varargs" => "args",
      "rettype" => "navrat",
      "params" => [
          "typ",
          "typ2"
      ]
    }
  );
  $delka = keys %funkce;
  $funkce{ "funkce" . ($delka + 1)} = {
      "file" => "soubor3",
      "name" => "jmeno3",
      "varargs" => "args",
      "rettype" => "navrat",
      "params" => [
          "typ",
          "typ2"
        ]
    };

But there is a problem. The last one hash is add as first in %function but I want It as a last one. How can I fix it? And I am doing it right? Thanks

Was it helpful?

Solution

Hashes do not guarantee insert order. You're asking it to hash your key, so x > y <=/=> f(x) > f(y)

If you want to guarantee insert order, although I see no reason to introduce the overhead (of a tie), a standard way is to use Tie::IxHash.

Lists have ends, not hashes. Hashes are a mathematical mapping from a set of names or ids to a set of objects or values. If we think of dog names to dogs then, despite that we can arrange the names of the dogs alphabetically, there really is no "first dog".

From what you show,

push( @funkce
    , { "file"    => "soubor1"
      , "name"    => "jmeno1"
      , "varargs" => "args"
      , "rettype" => "navrat"
      , "params"  => [ qw<typ typ2> ]
      });

will work just as good. There is little gain in typing $funkce{'funcke2'} rather than $funkce[2] or $funkce{ '$funkce' . $i } over $funkce[$i] and if you're going to increment other names besides, then you should have your division in this fashion: $funkce{'funkce'}[2] // $funkce{'superfunkce'}[2]

Using hashes for discrete parts of names and arrays for numbers is a good way to program your data. $funkce{'funkce'}[2] is every bit a singular entity as $funkce{'funkce2'}.

OTHER TIPS

If you need ordered items use an array, if you want named (unordered) items use a hash. To get something close to ordered hashes, you need either nested arrays/hashes or sort the hashes or use some tied class.

Nesting

 @funkce = (
    { name => "funkce1",
      "file" => "soubor1",
      "name" => "jmeno1",
      "varargs" => "args",
      "rettype" => "navrat",
      "params" => [
                "typ",
                "typ2"
            ]
    },
    { name => "funkce2",
      "file" => "soubor2",
      "name" => "jmeno2",
      "varargs" => "args",
      "rettype" => "navrat",
      "params" => [
          "typ",
          "typ2"
      ]
    }
  );
 push @funkce, {
  name => "funkce3",
  "file" => "soubor3",
  "name" => "jmeno3",
  "varargs" => "args",
  "rettype" => "navrat",
  "params" => [
      "typ",
      "typ2"
    ]
};

Sorting

%funkce = ( ... ); # as in OP

# when using
foreach my $item (sort keys %funkce) {
  # do something with $funkce{$item}
}

Tied

See Tie::IxHash but as Axeman said, you probably don't need/want this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top