Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re: grep and dereferencing an array of arrays

by McA (Priest)
on Sep 06, 2013 at 18:48 UTC ( #1052751=note: print w/ replies, xml ) Need Help??


in reply to grep and dereferencing an array of arrays

Hi,

you have an error here:

my $usefulans = grep { $$_[ 0 ] eq $answer } @$qablock;

With the assigmnent to $usefulans you force scalar context. That means you assign the length of the resulting grep operation to this variable. Afterwards you try to derefence it. I'm pretty sure that with strict and warnings you would have got the right hints.

Update: my $usefulans = [ grep { $$_[ 0 ] eq $answer } @$qablock ]; should solve your problem.

Best regards
McA


Comment on Re: grep and dereferencing an array of arrays
Select or Download Code
Re^2: grep and dereferencing an array of arrays
by oakb (Scribe) on Sep 06, 2013 at 19:02 UTC
    I thought the same thing. When I said that I've tried every permutation that I can imagine, my attempts included many variations on this:
    my $usefulans = [ grep { $$_[ 0 ] eq $answer } @$qablock ];
    ...which should make the assignment as an anonymous reference. But none of those worked any better than the bracket-less assignment. I still end up with the reference address.

    Update: you updated while I was replying. You probably have already seen me saying that adding brackets doesn't work.

      Can you show me Dumper($qablock);

      Update: I don't know what you want to achieve with the first code block. Do you really just want the last matching result?

      McA

        The program is a self-grading multiple-choice testing environment. The teacher can enter an arbitrary number of questions, with four possible answers to each question. Only one of the answers may be correct. The program randomizes the questions and answers, so a student will never get the same test twice (and can't cheat using a scoring key). This example is a simple spelling test. Three of the answers are wrong ('W') and one is right ('R'):
        ========== $VAR1 = [ [ 'a', 'W', 'interupt' ], [ 'b', 'R', 'interrupt' ], [ 'c', 'W', 'innterupt' ], [ 'd', 'W', 'intterupt' ] ]; ==========
        Since the answers have been randomized, the program has to match the entered answer letter ('a..d') to the 'W' or 'R' that is the second element of one of the elements of the $qablock. Only then can the actual answer be recorded for later scoring (since the answer 'b' has no lasting significance).

        The reason that I removed the square brackets from the grep is because the element of $qablock that the grep is assigning should already be an anonymous array reference. But then I still had to use the brackets for the assignment in the foreach, so I tried it with brackets as well. Basically, I've been flailing in the hope of getting lucky....
Re^2: grep and dereferencing an array of arrays
by Eily (Deacon) on Sep 06, 2013 at 20:42 UTC

    You're right about the mistake, except that what grep returns is already a hashref so by adding [ ] around it, you make an array of array

    You can just provide a list context to the expression with ($usefulans,) (the comma is optional, but I put it there to show that the parenthesis is there to force list context), which will put the first result into $usefulans and drop the others. But since there should be only one match ...

    $VAR1 = [ [ 'a', 'W', 'interupt' ], [ 'b', 'R', 'interrupt' ], [ 'c', + + + 'W', + + + 'innterupt' + + + ], + + + [ + + + 'd', + + + 'W', + + + 'intterupt' + + + ] + + + ]; + + + ($answer,) = grep { $$_[0] eq 'b' } @$VAR1; + + + print "@$answer";
    b R interrupt

    But oakb, you should consider a hash (with answer id as the key). You could easily turn your array into one with : %hash = map { shift @$_ => $_ } @$qablock Then you'd just have to do $hash{$givenAnswer} to get ['w', 'interupt']

      A ++ for your hash advice.

      McA

      Using a hash is a great idea, one that I contemplated earlier but discarded because other parts of the program rely on the data being maintained in an ordered list -- which arrays provide but hashes do not.

      Honestly, I'm still trying to get my head around why the grep returns its data in a list context while the foreach does not. I expected the two routines to be equivalent....

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1052751]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (9)
As of 2014-12-29 12:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (187 votes), past polls