简体   繁体   中英

Perl: Beginner. Which data structure should I use?

Okay, not sure where to ask this, but I'm a beginner programmer, using Perl. I need to create an array of an array, but I'm not sure if it would be better use array/hash references, or array of hashes or hash of arrays etc.

I need an array of matches: @totalmatches

Each match contains 6 elements(strings):

@matches = ($chapternumber, $sentencenumber, $sentence, $grammar_relation, $argument1, $argument2)

I need to push each of these elements into the @matches array/hash/reference, and then push that array/hash/reference into the @totalmatches array.

The matches are found based on searching a file and selecting the strings based on meeting the criteria.

QUESTIONS

  1. Which data structure would you use?

  2. Can you push an array into another array, as you would push an element into an array? Is this an efficient method?

  3. Can you push all 6 elements simultaneously, or have to do 6 separate pushes?

  4. When working with 2-D, to loop through would you use:

    foreach (@totalmatches) { foreach (@matches) {... } }

Thanks for any advice.

Which data structure would you use?

An array for a ordered set of things. A hash for a set of named things.

Can you push an array into another array, as you would push an element into an array? Is this an efficient method?

If you try to push an array (1) into an array (2), you'll end up pushing all the elements of 1 into 2. That is why you would push an array ref in instead.

Can you push all 6 elements simultaneously, or have to do 6 separate pushes?

Look at perldoc -f push

push ARRAY,LIST

You can push a list of things in.

When working with 2-D, to loop through would you use:

Nested foreach is fine, but that syntax wouldn't work. You have to access the values you are dealing with.

for my $arrayref (@outer) {
    for my $item (@$arrayref) {
        $item ...
    }
}

Do not push one array into another array. Lists just join with each other into a new list.

Use list of references.

#create an anonymous hash ref for each match
$one_match_ref = {
     chapternumber => $chapternumber_value, 
     sentencenumber => $sentencenumber_value, 
     sentence => $sentence_value,
     grammar_relation => $grammar_relation_value, 
     arg1 => $argument1, 
     arg2 => $argument2
};

# add the reference of match into array.
push @all_matches, $one_match_ref;

# list of keys of interest
@keys = qw(chapternumber sentencenumber sentence grammer_relation arg1 arg2);
# walk through all the matches.
foreach $ref (@all_matches) {
    foreach $key (@keys) {
        $val = $$ref{$key};

    }
    # or pick up some specific keys
    my $arg1 = $$ref{arg1};
}

Which data structure would you use?

An array... I can't really justify that choice, but I can't imagine what you would use as keys if you used a hash.

Can you push an array into another array, as you would push an element into an array? Is this an efficient method?

Here's the thing; in Perl, arrays can only contain scalar variables - the ones which start with $ . Something like...

@matrix = ();
@row = ();
$arr[0] = @row; # FAIL!

... wont't work. You will have to instead use a reference to the array:

@matrix = ();
@row = ();
$arr[0] = \@row;

Or equally:

push(@matrix, \@row);

Can you push all 6 elements simultaneously, or have to do 6 separate pushes?

If you use references, you need only push once... and since you don't want to concatenate arrays (you need an array of arrays) you're stuck with no alternatives;)

When working with 2-D, to loop through would you use:

I'd use something like:

for($i=0; $i<@matrix; $i++) {
    @row = @{$matrix[$i]}; # de-reference
    for($j=0; $j<@row; $j++) {
        print "| "$row[$j];
    }
    print "|\n";
}

Which data structure would you use?

Some fundamental container properties:

  • An array is a container for ordered scalars.

  • A hash is a container for scalars obtained by a unique key (there can be no duplicate keys in the hash). The order of values added later is not available anymore.

I would use the same structure like ZhangChn proposed.

Use a hash for each match. The details of the match then can be accessed by descriptive names instead of plain numerical indices. ie $ref->{'chapternumber'} instead of $matches[0] .

Take references of these anonymous hashes (which are scalars) and push them into an array in order to preserve the order of the matches.

To dereference items from the data structure

  • get an item from the array which is a hash reference

  • retrieve any matching detail you need from the hash reference

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM