0

I have the following code:

my @logs = split(",",$opts->{"logs"});
$opt_href->{"logs"} = \@logs;

It basically splits the $opts->{"logs"} by comma and keeps the array ref. Later I need to check if string exists in the $opt_href->{"logs"} array. Looking at this topic, I see that it's recommended to keep a hash, instead of array. I could just do:

my %logs;
for each my $log (split(",",$opts->{"logs"})) {
    $logs{$log} = 1;
}
$opt_href->{"logs"} = \%logs;

Is there a better way to do this? Maybe a one/two liners?

vesii
  • 2,760
  • 4
  • 25
  • 71
  • 1
    Re "*I see that it's recommended to keep a hash*", Not quite. A hash was recommended to implement a set. Are you trying to form a set from the values in `$opts->{logs}`? – ikegami May 08 '21 at 23:34
  • I agree with ikegami that it is not at all certain you need a hash. Especially with strings in manually edited option files. A hash will differentiate between `foo ` and `foo` and `FOO`, whereas for example a regex match can be made less strict. It all depends on what is important to your code. Checking a hash key vs looping through an array is a minor optimization in most cases. – TLP May 09 '21 at 10:58
  • @TLP They say that they "_need to check if string exists..._" and it seems that that's why they decided for a hash, as an efficient and handy look-up structure. This is then indeed a good solution, while I agree that it is not clear from the question whether that's the best way to organize data. (But that's not what they are asking so that's OK) – zdim May 09 '21 at 20:04

1 Answers1

5
my %logs = map { $_ => 1 } split /,/, $opts->{logs};
$opt_href->{logs} = \%logs;

Or, using the anonymous hash reference, constructed by { }

$opt_href->{logs} = { map { $_ => 1 } split /,/, $opts->{logs} };
zdim
  • 64,580
  • 5
  • 52
  • 81
  • "_anonymous hash reference, constructed by `{ }`_" --- to be more precise, the `{}` constructs an anonymous hash and returns a reference to it – zdim May 12 '21 at 05:43