Search code examples
arraysperlhashperl-data-structures

Perl: Counting elements in a complex data structure


I am new to complex data structures. I kind of understand the idea behind them but am having some difficulty getting the data out. I found out the structure of my current problem child by using Data::Dumper....

$VAR1 = {
      '4' => {
               'engine_coded' => 0,
               'name' => 'FILTER_1',
               'filter_actions' => {
                                     'X_Override_Queue_Level' => 'Value'
                                   },
               'filter_criteria' => [
                                      [
                                        'X_Charge',
                                        '=',
                                        'X_CHARGE_1'
                                      ]
                                    ]
             }
    };

What I am needing to do is make sure that given a filter name ("4" in this case") that "name" has a value, as well as "filter_actions" and "filter_criteria".

Anyone have an idea how to best accomplish this? Many thanks! Janie


Solution

  • Let's break this down into pieces...

    First, create a function which validates a structure:

    sub validate
    {
        my ($data) = @_;
    
        # always return true for now
        return 1;
    }
    

    Now let's start filling in the bits... you want to use a filter name as part of the validation checks, so let's add that as an argument:

    sub validate
    {
        my ($data, $filter_name) = @_;
    
        # always return true for now
        return 1;
    }
    

    Before doing anything else, it would make sense to check if that filter name exists as a key; if it doesn't, validation has failed:

    sub validate
    {
        my ($data, $filter_name) = @_;
    
        return if not exists $data->{$filter_name};
    
        # otherwise, return true
        return 1;
    }
    

    Now also check that there is a value. Since definedness in a hash key is a superset of 'exists' (any value that is defined must also exist, but not every value that exists needs to be defined - as undef could be the value), the first check can be omitted:

    sub validate
    {
        my ($data, $filter_name) = @_;
    
        return if not defined $data->{$filter_name};
    
        # otherwise, return true
        return 1;
    }
    

    We've checked that the filter_name key is present in the data and it is defined, but before looking one level deeper, we need to confirm that it really is a hashref:

    sub validate
    {
        my ($data, $filter_name) = @_;
    
        return if not defined $data->{$filter_name};
    
        return if ref $data->{$filter_name} ne 'HASH';
    
        # otherwise, return true
        return 1;
    }
    

    Now look for the 'filter_actions' and 'filter_criteria' keys under the filter name:

    sub validate
    {
        my ($data, $filter_name) = @_;
    
        return if not defined $data->{$filter_name};
    
        return if ref $data->{$filter_name} ne 'HASH';
    
        return if not defined $data->{$filter_name}{filter_actions};
        return if not defined $data->{$filter_name}{filter_actions};
    
        # otherwise, return true
        return 1;
    }
    

    That's it! Be sure to read up on using perl data structures in perldoc perlreftoot, perldoc perlref, and perldoc perldsc.