Re: Convert a string into a hash
by Your Mother (Archbishop) on Aug 14, 2009 at 21:41 UTC
|
I suspect all you want is-
my @code = split /,/, $tokens;
If you're keeping hash with indices as values, it makes more sense to use an array. There's also this if you really don't care about the indices-
my %code = map { $_ => 1 } split /,/, $tokens;
Update: there's also this but I think your original version is easier for most to read-
my %code;
my @code = split /,/, $tokens;
$code{$code[$_]} = $_ for 0 .. $#code;
| [reply] [d/l] [select] |
|
|
I do need the corresponding values, because I'll sort a given list of tokens from this set. johngg got the idea!
This was the best I could do:
my %code = ( my $i = 0 or map { $_ => $i++ } split /,/, $tokens );
but I wanted to have no temporary variables... ;-)
| [reply] [d/l] |
|
|
Conditional my isn't allowed. Besides, your code doesn't compile. You want
my %code = do { my $i = 0; map { $_ => $i++ } split /,/, $tokens };
If you really want no explicitely declared temp variables, you can use the following:
my %code = sub { map { $_[$_] => $_ } 0..$#_ }->( split /,/, $tokens )
+;
But honestly, there's no need to limit the scope that badly. Either of the following are quite suitable:
my $i = 0;
my %code = map { $_ => $i++ } split /,/, $tokens;
my @code = split /,/, $tokens;
my %code = map { $code[$_] => $_ } 0..$#code;
| [reply] [d/l] [select] |
|
|
|
|
|
|
|
I can see how you can do that but not why you'd want to do it. The array is sorted already. There is no information in a hash with index values that isn't in an array. So, unless I'm missing something, it buys you nothing except a speed penalty and obfuscates a simple operation/need. If you could explain what you're going to do with it in the end, you might get some more interesting answers approaches. :)
| [reply] |
|
|
|
|
|
|
|
|
|
Re: Convert a string into a hash
by johngg (Canon) on Aug 14, 2009 at 22:03 UTC
|
You could declare and populate the hash (along with the sequence counter) all in one go using a do block.
$ perl -e '
> my $tokens = q{32,15,4,72,13,28,14};
> my %code = do{
> my $i = 0;
> map { $_ => $i ++ } split m{,}, $tokens;
> };
> print qq{$_ => $code{ $_ }\n}
> for sort { $code{ $a } <=> $code{ $b } } keys %code;'
32 => 0
15 => 1
4 => 2
72 => 3
13 => 4
28 => 5
14 => 6
$
I hope this is helpful.
| [reply] [d/l] |
Re: Convert a string into a hash
by Marshall (Canon) on Aug 15, 2009 at 00:52 UTC
|
The code below demonstrates that $x (scalar), @x (list), %x (hash) are different things.
Your instinct that anything with Perl using array indices is probably wrong, is correct.
#!/usr/bin/perl -w
use strict;
use Data::Dumper;
my $tokens = "32,15,4,72,13,28,14";
my @tokens = (split/,/,$tokens);
my %tokens = map {$_ => 1}@tokens;
print Dumper (\%tokens);
__END__
Prints:
$VAR1 = {
'4' => 1,
'32' => 1,
'28' => 1,
'72' => 1,
'13' => 1,
'14' => 1,
'15' => 1
};
Reconsidering your requirements, and I will say that this is bizarre:
#!/usr/bin/perl -w
use strict;
use Data::Dumper;
my $tokens = "32,15,4,72,13,28,14";
my @tokens = (split/,/,$tokens);
my $i=0;
my %tokens = map {$_ => $i++}@tokens;
print Dumper (\%tokens);
__END__
Prints:
VAR1 = {
'4' => 2,
'32' => 0,
'28' => 5,
'72' => 3,
'13' => 4,
'14' => 6,
'15' => 1
};
Now again of course since this initialization, why would you need the scalar string at all?
my @tokens = qw (32 15 4 72 13 28 14);
my $i=0;
my %tokens = map {$_ => $i++}@tokens;
yields the same result as above.
Ok, I am going to go "crazy" here and ask why you want a hash in the first place? I am at a loss the see the usefulness of a hash here. Why do you think that you need it? | [reply] [d/l] [select] |
|
|
my $tokens = "32,15,4,72,13,28,14";
my %code = do { my $i = 0; map { $_ => $i++ } split /,/, $tokens };
my $list = "4,13,15";
my $ok;
for my $token (sort { $code{$a} <=> $code{$b} } split /,/, $list) {
print "$token ";
# more code with $token...
last if $ok;
}
__END__
15 4 13
Obviously, both $tokens and $list are dynamically loaded from somewhere else... | [reply] [d/l] |
|
|
This is a straight-forward implementation.
Post again if I didn't get it right....
#!/usr/bin/perl -w
use strict;
my $tokens = "32,15,4,72,13,28,14";
my @tokens = split (/,/, $tokens);
my $list = "4,13,15";
my @list = split (/,/,$list);
my %list = map {$_ => 1}@list;
my @ordered_nums = grep{$list{$_}}@tokens;
print "@ordered_nums\n";
__END__
PRINTS:
15 4 13
| [reply] [d/l] |
|
|
|
|
|
|
|
Ooops, mess up and double post...sorry....
This is a straight-forward implementation.
Post again if I didn't get it right....
#!/usr/bin/perl -w
use strict;
my $tokens = "32,15,4,72,13,28,14";
my @tokens = split (/,/, $tokens);
my $list = "4,13,15";
my @list = split (/,/,$list);
my %list = map {$_ => 1}@list;
my @ordered_nums = grep{$list{$_}}@tokens;
print "@ordered_nums\n";
__END__
PRINTS:
15 4 13
Update:
I would perhaps replace "list" with "list_order". Matter of choice.
| [reply] [d/l] |