Re: Transferring hash keys to array... Need help sorting
by huck (Prior) on Apr 21, 2017 at 02:53 UTC
|
I just bet that my @labels = sort keys %hash worked just fine didnt it? Your problem was that when you said tried to get the contents they didnt line up. So what you want is to line up the values of @contents with the values in @labels. It would have been nice if you showed us what you did try, but at one point i expect you had something like
my @labels; my @content;
for my $var (keys(%hash)){
push @labels,$var;
push @content,$hash{$var};
}
and that was when you were complaining they were random.
so what if i mentioned that keys %hash looks like an array. in fact you could have said my @arr=keys(%hash); for my $var(@arr) { ... }. And you have seen that sort in fact does sort character values like you want. so what if you said my @arr=keys sort(%hash); for my $var(@arr) { ... } what do you think would happen?. So lets go a step farther, keys looks like an array, sort takes an array and looks like an array. we could just double things up, for my $var(sort(keys(@arr))) { ... }
| [reply] [d/l] [select] |
|
|
So what you're suggesting is that the arrays are being sorted correctly, but just not aligned with one another? That makes sense so I could adjust accordingly per your advice here...
See I thought the problem might have been that I wanted to sort the keys (labels) according to the integer following "label" and that because I was using character sorting that's why it wasn't working. Or is that not the case?
| [reply] |
|
|
my @labels=sort {$hash{$a}<=>$hash{$b}} keys %hash;
my @content = @hash{@labels};
| [reply] [d/l] [select] |
Re: Transferring hash keys to array... Need help sorting
by tybalt89 (Monsignor) on Apr 21, 2017 at 03:11 UTC
|
#!/usr/bin/perl
# http://perlmonks.org/?node_id=1188504
use strict;
use warnings;
my %hash = qw( title1 1 title3 3 title4 4 title2 2 );
my @labels = sort keys %hash;
my @content = @hash{@labels};
use Data::Dumper;
print Dumper \%hash;
print "\n";
print Dumper \@labels;
print "\n";
print Dumper \@content;
| [reply] [d/l] |
|
|
In this instance, this would work. But what if the content for each element of that array is a string of characters and not numeric? (i.e. accaccacacaca)
| [reply] |
|
|
#!/usr/bin/perl
# http://perlmonks.org/?node_id=1188504
use strict;
use warnings;
my %hash = qw( title1 one title3 three title4 four title2 two );
my @labels = sort keys %hash;
my @content = @hash{@labels};
use Data::Dumper;
print Dumper \%hash;
print "\n";
print Dumper \@labels;
print "\n";
print Dumper \@content;
| [reply] [d/l] |
|
|
|
|
... what if the content for each element of that array is a string of characters and not numeric?
One interpretation:
c:\@Work\Perl\monks>perl -wMstrict -le
"use Data::Dump qw(dd);
;;
my %hash = qw(title1 uno title3 tres title4 quatro title2 dos);
;;
my @labels = sort keys %hash;
my @content = @hash{@labels};
;;
dd \%hash;
dd \@labels;
dd \@content;
"
{ title1 => "uno", title2 => "dos", title3 => "tres", title4 => "quatr
+o" }
["title1", "title2", "title3", "title4"]
["uno", "dos", "tres", "quatro"]
(BTW: This is something you could actually have tried for yourself!)
Update: The @hash{@labels} thing is a hash slice.
Give a man a fish: <%-{-{-{-<
| [reply] [d/l] [select] |
|
|
Re: Transferring hash keys to array... Need help sorting
by marioroy (Prior) on Apr 21, 2017 at 03:17 UTC
|
Hello DARK_SCIENTIST and welcome to the monastery.
Give Hash::Ordered a try. There is also MCE::Shared::Ordhash which can be constructed as a non-shared object. The two implementations are reasonably fast. The OO interface is faster whenever performance is desired.
use Hash::Ordered;
use MCE::Shared::Ordhash;
tie my %h1, 'Hash::Ordered', @pairs;
tie my %h2, 'MCE::Shared::Ordhash', @pairs;
my $h3 = Hash::Ordered->new( @pairs );
my $h4 = MCE::Shared::Ordhash->new( @pairs );
MCE::Shared::Ordhash supports OO and hash-like dereferencing at the same time. It's quite nice having OO for maximum performance and dereferencing when needed.
my $oh = MCE::Shared::Ordhash->new();
$oh->set( hello => "there" );
$oh->{hello} = "there"; # on-demand hash-like dereferencing
$oh->assign( @pairs );
Examples.
use Hash::Ordered;
tie my %h1, 'Hash::Ordered', qw( title1 foo title2 bar title3 baz );
my @labels1 = keys %h1;
my $h2 = Hash::Ordered->new(qw( title1 foo title2 bar title3 baz ));
my @labels2 = $h2->keys;
Both Hash::Ordered and MCE::Shared::Ordhash are light on memory consumption.
Regards, Mario. | [reply] [d/l] [select] |
Re: Transferring hash keys to array... Need help sorting
by Laurent_R (Canon) on Apr 21, 2017 at 06:24 UTC
|
You've been given good solutions to your problem, but I have the impression it might be the wrong problem.
See http://www.perlmonks.org/?node=xy+problem
Why do you want to have two arrays in sync? You probably want this because you don't know how to do something that could be done another easier way, so you come up with this question.
May be you should explain what you're really trying to do, tell us about the bigger problem at a higher level, it is quite likely there is a better way to do it.
| [reply] |
|
|
The reason I want array positions between the two arrays to be synced is because if I print label[0] and content[0] I want the label for a protein sequence to match the actual protein sequence itself
| [reply] |
|
|
| [reply] [d/l] |
|
|
|
|
|
|
|
It's usually easier to use $labels[0] and $hash{$labels[0]} instead of maintaining the same order in the content array. I think that's what Laurent is getting at. But if you really want to have a bunch of parallel arrays, here's the pattern for sorting them:
my @order = sort { $labels[$a] cmp $labels[$b] } 0 .. $#labels;
@labels = @labels[@order];
@content = @content[@order];
@more_content = @more_content[@order];
| [reply] [d/l] |
|
|
Re: Transferring hash keys to array... Need help sorting
by hippo (Archbishop) on Apr 21, 2017 at 08:28 UTC
|
I tried using something like "@labels = sort keys %hash" but this doesn't work.
Oh yes it does. SSCCE:
#!/usr/bin/env perl
use strict;
use warnings;
use Test::More tests => 2;
my %hash = (
alpha => 'one',
gamma => 'three',
beta => 'two'
);
my @wantkeys = qw/alpha beta gamma/;
my @wantvals = qw/one two three/;
my @labels = sort keys %hash;
is_deeply \@labels, \@wantkeys, "You said this doesn't work, but it do
+es";
my @vals = @hash{@labels};
is_deeply \@vals, \@wantvals, "The values match up with the keys";
| [reply] [d/l] |