Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Sorry for the late reply, I've been polishing this a while, because I did not want yet another negative score (bums me out).</p> <p>This is an interesting efficiency problem. I don't know if my solution will work for you, but I thought I would share it anyway. It is probably efficient only if your arrays do not change too often, and if your arrays contain many duplicate values. I have not run any efficiency checks on it.</p> <p>Basically, the solution is to remove one dimension of the cross checking by turning the array values into bits, and doing a bitwise comparison on the entire array in one go. Array values are deduped, sorted and given a serial number. The arrays total serial numbers are then stored in a single value by bitwise or. A single array can thereby be checked for a single serial number with only one operation, e.g.:</p> <p><code>if ( array &amp; serialno )</code></p> <p>It will require one run to prepare the data, which can then be saved in cache or similar. This data can then be used until your data changes (e.g. files/folders are removed or added). I have added a fatal exit on undefined values, which means the data must be refreshed when it occurs.</p> <p>Good luck!</p> <pre><code>use strict; use warnings; my @list1=('a', 'b', 'c'); my @list2=('a', 'b', 'f'); my @list3=('e', 'd', 'a'); my @list4=('f', 'g', 'h'); # combine arrays my @total = (@list1, @list2, @list3, @list4); # dedupe (Thanks Xetius for this code snippet) my %unique = (); foreach my $item (@total) { $unique{$item} ++; } # Default sort(), don't think it matters @total = sort keys %unique; # translate to serial numbers my %serials = (); for (my $num = 0; $num &lt;= $#total; $num++) { $serials{$total[$num]} = $num; } # convert array values to serial numbers, and combine them my @tx = (); for my $entry (@list1) { $tx[0] |= 2**$serials{$entry}; } for my $entry (@list2) { $tx[1] |= 2**$serials{$entry}; } for my $entry (@list3) { $tx[2] |= 2**$serials{$entry}; } for my $entry (@list4) { $tx[3] |= 2**$serials{$entry}; } &amp;print_all; sub inList { my ($value, $list) = @_; # Undefined serial numbers are not accepted if (! defined ($serials{$value}) ) { print "$value is not in the predefined list.\n"; exit; } return ( 2**$serials{$value} &amp; $tx[$list] ); } sub yesno { my ($value, $list) = @_; return ( &amp;inList($value, $list) ? "yes":"no" ); } # # The following code is for printing purposes only # sub print_all { printf "%-6s %-6s %-6s %-6s %-6s\n", "", "List1", "List2", "List3", "List4"; print "-" x 33, "\n"; &amp;table_print(@list1); &amp;table_print(@list2); &amp;table_print(@list3); &amp;table_print(@list4); } sub table_print { my @list = @_; for my $entry (@list) { printf "%-6s %-6s %-6s %-6s %-6s\n", $entry, &amp;yesno($entry, 0), &amp;yesno($entry, 1), &amp;yesno($entry, 2), &amp;yesno($entry, 3); } print "-" x 33, "\n"; } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload