in reply to Determine if array value in string results

Hi, the classic technique for finding out whether an element of one array is present in another array is to make a hash lookup table.

use strict; use warnings; my @to_be_searched = qw/ lots of elements /; my @to_find = qw/ fewer elements /; my %lookup = map { $_ => 1 } @to_be_searched; for my $element ( @to_find ) { if ( exists $to_be_searched{ $element } ) { # do something } else { # do other thing } }
(In your case you may need to do something to $element (capture part of it via regexp?) and use the product of that to search the lookup table.)

Hope this helps!


The way forward always starts with a minimal test.

Replies are listed 'Best First'.
Re^2: Determine if array value in string results
by ImJustAFriend (Scribe) on Nov 21, 2018 at 20:05 UTC
    Thank you 1nickt I implemented your idea, slightly modified based on my situation, so it looks like this:
    if ( $RESULT eq "" ) { print DEBUG1 "Line is \"" . $line ."\"\n"; my $action = substr($ACTION, 0, 1); open OUT4, ">>", $csvtogo or die "Could not op +en OUT4: $!\n"; if ( $line =~ /parameters\ after\ change/ ) { #Start of block to manage $inblock = 1; next; } # Skip handling line unless we are in a block next unless ( $inblock ); if ( $line =~ /NRG\ location/) { print OUT4 "$timestamp;$action;"; # Block ends here # Process all blocked lines stored in +@blocklines my ($k, $v); my @fields; my %lookup = map { $_ => 1 } @csvfield +list; foreach my $bline (@blocklines) { print DEBUG1 "bline: \"$bline\ +"\n"; my ($k, $v) = split '=', $blin +e; push @fields, $k; } print DEBUG Dumper (\@fields); for my $element ( @fields ) { if (exists $lookup{$element}) +{ print OUT4 "yes;"; } else { print OUT4 ";"; } } print OUT4 "\n" #Cleanup block now that it has been pr +ocessed @blocklines = (); $inblock = 0; next; } # Just a line we want to process within the bl +ock # Push it into @blocklines so we can process i +t push @blocklines, $line; next; }
    When I look at my results file (OUT4), I see this (in part):
    2018_11_20-11_15_58;C;;yes;;;; 2018_11_20-11_15_58;C;yes;yes;yes;yes;yes;yes;yes;yes;yes;yes;yes;yes; +yes;yes;yes;yes;yes;yes;;;;;yes;yes;yes;yes;yes;yes;yes;;;;;;;;;;; 2018_11_20-11_15_58;C;;; 2018_11_20-11_15_58;C;yes;yes;yes;yes;; 2018_11_20-11_15_58;C;yes;yes; 2018_11_20-11_15_58;C;yes;yes; 2018_11_20-11_15_58;C;yes;yes; 2018_11_20-11_15_58;C;yes;;;; 2018_11_20-11_15_58;C;yes;;;;; 2018_11_20-11_15_58;C;yes; 2018_11_20-11_15_58;C;yes;yes;yes;; 2018_11_20-11_44_51;C;;yes;;;; 2018_11_20-11_44_51;C;yes;yes;yes;yes;yes;yes;yes;yes;yes;yes;yes;yes; +yes;yes;yes;yes;yes;yes;;;;;yes;yes;yes;yes;yes;yes;yes;;;;;;;;;;;
    Each line above should be MUCH longer. When I print @fields to DEBUG, I get this (in part):
    $VAR1 = [ 'algorithmPosition', 'authenticationSubscriberType', 'k4id', 'OP_id', 'authKey' ]; $VAR1 = [ 'mobileNetworkCodeId', 'mobileCountryCodeId', 'chargingGatewayFuncHost', 'chargingGroup', 'S6aRoamingRestrictionType', 'pcscfServerName', 'maxRequestedBandwidthUL', 'maxRequestedBandwidthDL', 'epsAccessSubscriptionType', 'epsAccessSubscriptionType', 'odbSpecificToPs', 'psRoamingRestrictionType', 'chargingCharacteristics', 'odbCustoPremRateCalls', 'odbOutgoingCalls', 'accessRestrictionData', 'networkAccessMode', 'mSubIdentificationNumberId', 'GcsServiceProfile', 'OdbServiceProfile', 'MainSNwithBearerService', 'MainSNwithBearerService', 'cwTSSpeechActivationFlag', 'callWaitingProvisionedFlag', 'clipProvisionedFlag', 'mptyProvisionedFlag', 'callHoldProvisionedFlag', 'clirProvisionedFlag', 'csRoamingRestrictionType', 'eps3gppRestrictionListNum', 'psRestrictionListNum', 'csRestrictionListNum', 'packetMsAddressList', 'packetMsAddressList', 'framedPoolSetList', 'framedPoolSetList', 'epsApnContextSetList', 'epsApnContextSetList', 'epsServiceProfile' ]; $VAR1 = [ 'serverCapIdx', 'chargingIdx' ]; $VAR1 = [ 'authEntryType', 'hlrIndicator', 'protocolCap', 'authSchema', 'imsi' ]; $VAR1 = [ 'puidType', 'unregSvcInd' ]; $VAR1 = [ 'puidType', 'unregSvcInd' ]; $VAR1 = [ 'puidType', 'unregSvcInd' ];
    Do I need to include the whole 900+ item array as well? Or can you see what's going on based on what you see here? Thanks again!

      Hi again. First, no way you should be producing your output like that. That kind of manual jiggery-pokery is fraught with pitfalls and error vectors. You need to build up a data structure known as an array of arrays representing your output, and then convert it to the delimited file using Text::CSV or Text::CSV_XS.

      As to your problem: you are building a lookup table from the wrong structure. If what you want to do is check all fields in @csvfieldlist to see which are present in @fields, and record a null value for those that are not, you need to make the lookup table from @fields and loop through the larger list.

      use Text::CSV_XS; my @rows; for my $line ( @something ) { if ( $line =~ /NRG\ location/) { my @row; my @fields; foreach my $bline (@blocklines) { my ($k, $v) = split '=', $bline; push @fields, $k; } my %lookup = map { $_ => 1 } @fields; for my $field ( @csvfieldlist ) { if ( exists $lookup{ $field } ) { push @row, 'yes'; } else { push @row, undef; } } push @rows, \@row; } } csv (in => \@rows, out => "file.csv", sep_char=> ";");

      Hope this helps!


      The way forward always starts with a minimal test.
        Thank you so much for the assist - this worked awesomely! Now I'll (hopefully) know for next time something like his arises! :)