There is a list of available tokens, where one token is "better" than other if it appears previously on that ranking list. From the tokens list given in the first post of this thread, 4 is "better" than 13, and 15 is the "best" of that three tokens.

The list of tokens is defined once at startup, based on config and user params.

There is another list from where I must select the "best" token. This list changes on each iteration based on input.

... and the requirement changed again!!! on each list from the input can appear other tokens than the valid ones(from tokens list), so I need to discard them. If none of the input's tokens is on the ranking, I must take a default one (the last from the ranking, better than nothing).

Constructing the hash once for the ranking:

#!perl -w use strict; my $tokens = "32,15,4,72,13,28,14"; my %ranking = do { my $i; map { $_ => $i++ } split /,/, $tokens }; my ($default) = ($tokens =~ m/,(\d+)$/); # last token while (my $list = <DATA>) { chomp $list; my $best = $default; for my $b (split /,/, $list) { next unless defined $ranking{$b}; $best = $b if $ranking{$b} < $ranking{$best}; } print "$best\n"; } __DATA__ 4,13,15 4,50,15,13 50,60,70

Using your approach, where the hash must be constructed for each input line:

#!perl -w use strict; my $tokens = "32,15,4,72,13,28,14"; my @ranking = split (/,/, $tokens); my $default = $ranking[$#ranking]; # last token while (my $list = <DATA>) { chomp $list; my %list = map {$_ => 1} split /,/, $list; my $best = ( grep {$list{$_}} @ranking )[0] || $default; print "$best\n"; } __DATA__ 4,13,15 4,50,15,13 50,60,70

Both examples should print 15, 15 and 14.

So, which approach is better? Speed is not an issue (actually, input is retrieved from an external website, one html page, one data row of tokens). Size of tokens lists (initial and input) is not so long at the time (less than 15 values).

A better (obfuscated) way to write the for of the first program? The next unless defined condition could be removed if the $i variable from the ranking population is initialized with a high value and then decrease the counter on each iteration of the map, but a message will be displayed because of use warnings.


In reply to Re^6: Convert a string into a hash by vitoco
in thread Convert a string into a hash by vitoco

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.