I'd like to create an array of unique values

M

Mr P

Sounds just like keys %h don't it.

Starting with

$_ =
"cat
man
dog
mouse
man
man
";

I want to end up with

[cat man dog mouse]

My approach is:

my @s = split /\n/;
# unique-afy it!
my %s;
@s{@s} = @s;
@s = keys %s;

My PREFERENCE is to not have to involve both a hash and an array, and
also to not have to include a non-native lib module.

Is there a syntax I can use to just work with the hash and populate
the keys-only directly from the split? I don't really care what the
values are. I don't even care if they are undef.


Thank-You, Peristas,

MP
 
G

Greg Bacon

: Is there a syntax I can use to just work with the hash and populate
: the keys-only directly from the split? I don't really care what the
: values are. I don't even care if they are undef.

You can condense your code a little:

my %seen;
my @s = grep !$seen{$_}++, split /\n/;

Hope this helps,
Greg
 
P

Paul Lalli

Sounds just like keys %h don't it.

Starting with

$_ =
"cat
man
dog
mouse
man
man
";

I want to end up with

[cat man dog mouse]

My approach is:

my @s = split /\n/;
# unique-afy it!
my %s;
@s{@s} = @s;
@s = keys %s;

My PREFERENCE is to not have to involve both a hash and an array, and
also to not have to include a non-native lib module.

Is there a syntax I can use to just work with the hash and populate
the keys-only directly from the split? I don't really care what the
values are. I don't even care if they are undef.

I don't think you're going to get around using both a hash and an
array, without some serious mumbo-jumbo involving repeatedly looping
through the array as you're building it. That will be unreadable and
inefficient.

The "right" answer is:
my %h = map { $_ => 1 } split /\n/, $_;
my @s = keys %h;

If you're worried about having too many named variables, however, you
could sacrifice some readability by making the hash anonymous:

my @s = keys %{ {map { $_ => 1 } split /\n/, $_} };

Perhaps you should be asking yourself why you're making this
constraint, however.

Paul Lalli
 
C

Charlton Wilbur

P> my @s = split /\n/;
P> my %s;
P> @s{@s} = @s;
P> @s = keys %s;

P> My PREFERENCE is to not have to involve both a hash and an
P> array, and also to not have to include a non-native lib module.

Well, those are your two options.

You can use a hash and an array, or you can include a non-core module.

P> Is there a syntax I can use to just work with the hash and
P> populate the keys-only directly from the split? I don't really
P> care what the values are. I don't even care if they are undef.

my %s;
$s{$_}++ foreach (split /\n/);
keys %s;

Note that you're not really eliminating the array, though -- you're
just using it implicitly in the foreach loop.

Charlton
 
J

John W. Krahn

Mr said:
Sounds just like keys %h don't it.

Starting with

$_ =
"cat
man
dog
mouse
man
man
";

I want to end up with

[cat man dog mouse]

My approach is:

my @s = split /\n/;
# unique-afy it!
my %s;
@s{@s} = @s;
@s = keys %s;

My PREFERENCE is to not have to involve both a hash and an array, and
also to not have to include a non-native lib module.

Is there a syntax I can use to just work with the hash and populate
the keys-only directly from the split? I don't really care what the
values are. I don't even care if they are undef.

$ perl -le'
$_ =
"cat
man
dog
mouse
man
man
";

my @s = do {
my %unique;
grep !$unique{$_}++, split /\n/;
};

print for @s;
'
cat
man
dog
mouse



John
 
M

Mirco Wahab

Mr said:
Starting with
$_ =
"cat
man
...
[cat man dog mouse]

My approach is:
...
My PREFERENCE is to not have to involve both a hash and an array, and
also to not have to include a non-native lib module.

Is there a syntax I can use to just work with the hash and populate
the keys-only directly from the split? I don't really care what the
values are. I don't even care if they are undef.


The closest I could come up with is
a simple match against a code assertion:

....

my %h;
$_ ='
cat
man
dog
mouse
man
man
';

() = /(\w+)(?{$h{$1}=undef})/g;

print " [@{[keys %h]}]";

....

but I couldn't get your correct order ;-)

Regards

M.
 
M

Mirco Wahab

Mirco said:
print " [@{[keys %h]}]";

Stupid, because the hash slice *does*
already provide list context, so a simple:


@h{/(\w+)/g} = undef;

print " [@{[keys %h]}]";


would be all what's necessary.
(did too much php lately ;-)

Regards

M.
 
J

Jürgen Exner

Mr said:
Starting with
$_ =
"cat
man
dog
mouse
man
man
";

I want to end up with

[cat man dog mouse]

My approach is:

my @s = split /\n/;
# unique-afy it!
my %s;
@s{@s} = @s;

You can split() directly into a hash slice without reading the words into an
array first:

@s{split/\n/} = undef;
@s = keys %s;

But that doesn't save you from still using keys() to get the list of unique
words.

jue
 
J

Jorge

Sounds just like keys %h don't it.

Starting with

$_ =
"cat
man
dog
mouse
man
man
";

I want to end up with

[cat man dog mouse]

My approach is:

my @s = split /\n/;
# unique-afy it!
my %s;
@s{@s} = @s;
@s = keys %s;

My PREFERENCE is to not have to involve both a hash and an array, and
also to not have to include a non-native lib module.

Is there a syntax I can use to just work with the hash and populate
the keys-only directly from the split? I don't really care what the
values are. I don't even care if they are undef.

Thank-You, Peristas,

MP

using arrays only --

my @arr = qw(cat man dog mouse man man);

my $prev = 'none';

my @sorted_arr = sort(@arr);

my @uniq_arr = grep($_ ne $prev && ($prev = $_), @sorted_arr);

foreach my $uniq(@uniq_arr){
print $uniq, "\n";
}

cat
dog
man
mouse
 
B

Brian McCauley

@h{/(\w+)/g} = undef;

That is a list assignment so the RHS evaluates to a list containing a
single undef element.

Although that would work (as would _any_ list) it would be more
idiomatic to write:

@h{/(\w+)/g} = ();
 
S

sujay.tukai

Sounds just like keys %h don't it.

Starting with

$_ =
"cat
man
dog
mouse
man
man
";

I want to end up with

[cat man dog mouse]

My approach is:

my @s = split /\n/;
# unique-afy it!
my %s;
@s{@s} = @s;
@s = keys %s;

My PREFERENCE is to not have to involve both a hash and an array, and
also to not have to include a non-native lib module.

Is there a syntax I can use to just work with the hash and populate
the keys-only directly from the split? I don't really care what the
values are. I don't even care if they are undef.

Thank-You, Peristas,

MP


I feel this is the shortest answer to ur query.

perl -e '$_ = "dog
man
dog
cat
mouse
man
man";
my %tmp; my @a;
@a = map {$tmp{$_}=$_ if(! $tmp{$_});} split("\n",$_);
print @a;'
 

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
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top