how do I create a hash from the list

N

Nene

I just used regular expressions to parse out an IP and port. Now how
do I create a hash from the list.

Here is the regex I used:
perl -ne 'print "$1 $2\n" if /http:\/\/(\S+):(\d+)\/' {} \; | sort |
uniq

The output of that command is:
10.10.24.131 7002
10.10.24.142 7504
10.10.24.144 7506
10.10.24.150 7512
10.10.24.151 7413
10.10.24.151 7513
10.10.24.151 7613
 
R

Rainer Weikusat

Nene said:
I just used regular expressions to parse out an IP and port. Now how
do I create a hash from the list.

Here is the regex I used:
perl -ne 'print "$1 $2\n" if /http:\/\/(\S+):(\d+)\/' {} \; | sort |
uniq

'$hash{$1} = $2 if ...' ?
 
J

Jürgen Exner

Nene said:
I just used regular expressions to parse out an IP and port. Now how
do I create a hash from the list.

There are many different ways to create many different hashes. What is
the desired structure/content of that hash (you forgot to tell us....)?

jue
 
B

Ben Bacarisse

Nene said:
I just used regular expressions to parse out an IP and port. Now how
do I create a hash from the list.

Here is the regex I used:
perl -ne 'print "$1 $2\n" if /http:\/\/(\S+):(\d+)\/' {} \; | sort |

Looks like there might be a missing / in there. See below...

While you say more about the hash you want to create, here's a tip: you
don't have to use // for regular expressions. If you precede the
expression with 'm' you can use something that is more convenient

if /http:\/\/(\S+):(\d+)\//

becomes

if m!http://(\S+):(\d+)/!

or even

if m{ http:// (\S+) : (\d+) / }x

(the trailing x lets you add space).

<snip>
 
S

sln

I just used regular expressions to parse out an IP and port. Now how
do I create a hash from the list.

Here is the regex I used:
perl -ne 'print "$1 $2\n" if /http:\/\/(\S+):(\d+)\/' {} \; | sort |
uniq

The output of that command is:
10.10.24.131 7002
10.10.24.142 7504
10.10.24.144 7506
10.10.24.150 7512
10.10.24.151 7413
10.10.24.151 7513
10.10.24.151 7613

You could create an array for the ports.

-sln

-----------------------
use strict;
use warnings;

my @data = (
'10.10.24.131 7002',
'10.10.24.142 7504',
'10.10.24.144 7506',
'10.10.24.150 7512',
'10.10.24.151 7413',
'10.10.24.151 7513',
'10.10.24.151 7613',
);

my %gameservers;

for (sort @data)
{
if (/^(\S+)\s+(\d*)$/) {
push @{$gameservers{$1}}, $2;
}
}

for my $addr (sort keys %gameservers)
{
print "adress: $addr ports: ";
for my $port (sort @{$gameservers{$addr}}) {
print "$port, ";
}
print "\n";
}

-------------------
Output:

adress: 10.10.24.131 ports: 7002,
adress: 10.10.24.142 ports: 7504,
adress: 10.10.24.144 ports: 7506,
adress: 10.10.24.150 ports: 7512,
adress: 10.10.24.151 ports: 7413, 7513, 7613,
 
C

ccc31807

I just used regular expressions to parse out an IP and port. Now how
do I create a hash from the list.

Here is the regex I used:
perl -ne 'print "$1 $2\n" if /http:\/\/(\S+):(\d+)\/' {} \; | sort |
uniq

The output of that command is:
10.10.24.131 7002
10.10.24.142 7504
10.10.24.144 7506
10.10.24.150 7512
10.10.24.151 7413
10.10.24.151 7513
10.10.24.151 7613

Perl flattens lists, and a hash is just a flattened list with
alternating values. For example:

my %colors = ("A","Apple","B","Bannana","C","Cumquat","D","Date");

Alternatively:

my %colors = (A => "Apple, B => "Bannana", C => "Cumquat", D =>
"Date");

The => operator is just a shorthand for a comma and quote in a list.

CC.
 
T

Ted Zlatanov

RW> '$hash{$1} = $2 if ...' ?

It's very unlikely the OP will want to do what you suggest, since he
shows two clearly identical IPs with different ports:

10.10.24.131 7002
10.10.24.142 7504
10.10.24.144 7506
10.10.24.150 7512
10.10.24.151 7413
10.10.24.151 7513
10.10.24.151 7613

Your way would lose the first two ports for 10.10.24.151.

I typically do this two ways, either

push @{$hash{$1}}, $2 if ... # keep an array of all the ports in order seen

or

$hash{$1}->{$2}++ # keep a hash of all the ports with a count of each

Of course the OP may need something else--it's not clear what, but I
would guess it's some variation of the two storage methods above.

Ted
 
J

James

RW> '$hash{$1} = $2 if ...' ?

It's very unlikely the OP will want to do what you suggest, since he
shows two clearly identical IPs with different ports:

10.10.24.131 7002
10.10.24.142 7504
10.10.24.144 7506
10.10.24.150 7512
10.10.24.151 7413
10.10.24.151 7513
10.10.24.151 7613

Your way would lose the first two ports for 10.10.24.151.

I typically do this two ways, either

push @{$hash{$1}}, $2 if ... # keep an array of all the ports in order seen

or

$hash{$1}->{$2}++ # keep a hash of all the ports with a count of each

Of course the OP may need something else--it's not clear what, but I
would guess it's some variation of the two storage methods above.

Ted

Generally speaking,

@a = qw/aa 1 bb 2 cc 3 dd 4/;
@b = map {$_%2?"":$_} 0..$#a;
%h = map {$a[$_] => $a[$_+1]} @b;
print "$_=>$h{$_}\n" for sort keys %h;

You get,
aa=>1
bb=>2
cc=>3
dd=>4

JL
 
U

Uri Guttman

J> Generally speaking,

J> @a = qw/aa 1 bb 2 cc 3 dd 4/;

and this does the same thing as your 3 lines. i am not sure what your
point is here.

%h = qw/aa 1 bb 2 cc 3 dd 4/;

J> @b = map {$_%2?"":$_} 0..$#a;

that doesn't do what you seem to think it does. print it with
Data::Dumper.

J> %h = map {$a[$_] => $a[$_+1]} @b;

if you had warnings enabled it would tell you something is wrong there.

J> print "$_=>$h{$_}\n" for sort keys %h;

have you ever heard of horizontal whitespace? it helps.

uri
 
T

Ted Zlatanov

J> Generally speaking,

J> @a = qw/aa 1 bb 2 cc 3 dd 4/;
J> @b = map {$_%2?"":$_} 0..$#a;
J> %h = map {$a[$_] => $a[$_+1]} @b;
J> print "$_=>$h{$_}\n" for sort keys %h;

J> You get,
J> aa=>1
J> bb=>2
J> cc=>3
J> dd=>4

That's not general, readable, or correct. As Uri said you can simply
assign the first qw// you gave to a hash and it Just Works. But consider

%a = qw/aa 1 bb 2 cc 3 dd 4 aa 5/;

Is the 'aa' key 1 or 5? Your approach has the same flaw, it will wipe
the 'aa' key.

My suggestion, which you perhaps quoted without understanding it
completely, ends up with

# preserve all elements in order
%a = ( aa => [ 1, 5 ], bb => [ 2 ], cc => [ 3 ], dd => [ 4 ] );

or with

# preserve element frequencies (they are all 1 here)
%a = ( aa => { 1 => 1, 5 => 1 }, bb => ( 2 => 1 ), cc => ( 3 => 1 ), dd => ( 4 => 1 ) );

which are both useful depending on the need. Also see Hash::Merge on
CPAN for a general solution to this well-known data structure problem.

Ted
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,008
Messages
2,570,268
Members
46,867
Latest member
Lonny Petersen

Latest Threads

Top