perlish has asked for the wisdom of the Perl Monks concerning the following question:

Good day..
I need a small application that will get a single word from users then I need to split the word into Chars. Ok till here is ok .. but how can I return the sum of the characters values upon a table predefined .. for example:
A= 123 , b = 200 , c =700 … z=800
So if the $word = ab , it should return 323.
Please bare with me I am new to perl.

Replies are listed 'Best First'.
Re: Alphabetical values
by moritz (Cardinal) on Dec 16, 2008 at 07:48 UTC
    Use a hash:
    my %freq = ( a => 123, b => 200, c => 700, ... z => 800, ); my $sum = 0; for (split //, $word) { $sum += $freq{$_}; } print "Sum: $sum\n";

    Note that the lookup is case sensitive, so may you need lc or uc to fix that.

    See perlintro and perldata.

Re: Alphabetical values
by ikegami (Patriarch) on Dec 16, 2008 at 07:49 UTC

    Use a hash for the table.

    my %table = ( A => 123, b => 200, ... ); my $sum = 0; $sum += $table{$_} for split //, $word;
      thank you for your quick response ikegami & moritz
Re: Alphabetical values
by dharanivasan (Scribe) on Dec 16, 2008 at 10:22 UTC
    use strict; use warnings; my %index = ( a => 123, b => 200, c => 700, ); my $word = "abc"; my $sum = 0; map { $sum += $index{$_}} split (//,$word); print $sum;

      Warning: useless use of map in void context.

      Ok, so perl may not be giving that to you, but some of us think it should ;-)

      This is the same, but has no return value (well, other than the final $sum, but most of us forget that):

      $sum += $index{$_} for split //, $word;
      Though, that said, I would still end up using map:
      use List::Util qw(sum) my $sum = sum map $index{$_}, split //, $word;
      My method has the advantage of reading more like English, and the disadvantage of likely being slower and using more memory. That said, it's always important to me that my code looks more like my design docs than like the underlying machine code, though I have to admit that $sum += $index{$_} is just so idiomatic that my mind sees "sum of $index{$_}" when my eyes see "$sum += $index{$_}". I just had to present it as yet another WTDI.

      I would think that map is inappropriate here since you are using it in a void context. foreach makes much more sense, as moritz and ikegami have done.

      Update: Tanktalus beat me to it.

Re: Alphabetical values
by jwkrahn (Abbot) on Dec 16, 2008 at 19:31 UTC

    And of course, you don't have to split the string into a list:

    my $sum = 0; while ( $word =~ /(.)/g ) { $sum += $freq{ $1 }; } print "Sum: $sum\n";