Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Method to turn an array into a hash #172

Closed
schwern opened this issue Jan 24, 2011 · 10 comments
Closed

Method to turn an array into a hash #172

schwern opened this issue Jan 24, 2011 · 10 comments

Comments

@schwern
Copy link
Contributor

schwern commented Jan 24, 2011

I write this a lot:

my %hash = map { $_ => 1 } @array;

Usually because I want to check if there's an element in @array a lot.

So my %hash = @array->as_hash seems sensible. Should it do anything else?

@exodist
Copy link
Contributor

exodist commented Jan 24, 2011

I think that is too ambuguous. Most perl peopel know that %thing = @thing works to turn an array of key, value pairs into a list. Many might see this method and just assume it is that and think it is pointless.

Even more concerning is that some people not as familiar with perl might think it does that not realising it is so easy on it's own. Truth be told %things = @things sounds to me like an @Array->as_hash too.

perhaps:

@Array->as_hash_keys( $value )
@Array->pair_to( $value )
@Array->hash_map()
@Array->truth_hash()
@Array->present( $want ) # Where the object itself keeps a cached copy of the array mapped to a hash, and re-maps it when the array changes?

@jarich
Copy link

jarich commented Jan 24, 2011

@exodist:

my %hash = @array;

is completely different from:

my %hash = map { $_ => 1 } @array;

@schwern: I usually write:

my %hash;
@hash{@array} = ():

which is more verbose, but importantly is different again. Perhaps giving a value is a good idea.

@exodist
Copy link
Contributor

exodist commented Jan 24, 2011

@jarich, please re-read my comment in detail. I know the 2 things are different, that was my whole point. The point was that the name could resonably apply to either and is thus ambiguous.

@notbenh
Copy link
Contributor

notbenh commented Jan 24, 2011

I feel like I've solved this already with hash_from_list ( https://github.com/notbenh/random_odds_and_ends/blob/master/Data/Manip.pm ) though it's never been posted to CPAN for exactly the reasons stated here, everyone who needs this already built there own or would likely be confused by the idea.

The code is a bit more verbose then is needed but it's the same idea.

@doherty
Copy link
Contributor

doherty commented Jan 30, 2011

The use case schwern used my %hash = map { $_ => 1 } @array; for is better accomplished with the lovely ~~, which is included in 5.10.0, which perl5i requires... though the semantics changed in 5.10.1... is 5.10.0 enough, or should we require 5.10.1? (or maybe by the time perl5i::3 is ready, will we want to require 5.12.something)

@schwern
Copy link
Contributor Author

schwern commented Feb 3, 2011

I'd forgotten ~~ does that.

The issue I have with ~~ is it does an O(n) search rather than O(1). However, for most uses of the array2hash technique, the array is so small it probably doesn't matter.

@flowchartsman
Copy link

I think it's a fairly useful thing to have under certain circumstances. Like you say, smartmatch is O(n) while using a lookup table is O(1). I would much rather generate a hash if I have, say, a huge list I only need to prepare once but might look through hundreds or even thousands of subsequent times. I'd say that's the main usage for such a method anyway, so why not give it a name that's suggestive of same? Like:

@Array->lookuptable
or
@Array->valuehash ?

@qrazhan
Copy link
Contributor

qrazhan commented Nov 22, 2011

Hello, I am working on this issue for my GCI task. I ran into something I don't quite understand and was hoping someone could explain it to me. So I added this code to the ARRAY.pm file:

method as_hash{
my @Result = map{ $_ => 1 } @$self;
return wantarray ? @Result : @Result;
}

But when I try to do:
my @arr = ("x", "y", "z");
my %hash = @arr->as_hash;
I get a "Can't call method "as_hash" on unblessed reference" error. Could someone explain what I'm doing wrong?

@schwern
Copy link
Contributor Author

schwern commented Nov 22, 2011

It works for me™.

There's few possibilities.

  • You didn't use perl5i::2 (just covering all the bases)
  • You didn't point perl at the new version of the library, usually done with perl -Ilib yourprogram or prove -l foo.t when testing.

schwern added a commit that referenced this issue Nov 23, 2011
schwern added a commit that referenced this issue Nov 23, 2011
* Consistent use of my (as required by perl5i)

* Consistent use of spacing in map blocks

* Be a little more cagey about exactly what the value will be.
  This will let us change it in the future if necessary.

* Show a real world example of use

For #172
schwern added a commit that referenced this issue Nov 23, 2011
Bump the future version number for a feature change.

For #172
@schwern
Copy link
Contributor Author

schwern commented Nov 23, 2011

There was a lot of debate over minor details of this, but on the principle of "the patch wins", I've merged in @qrazhan's work. It implements a straightforward @array->as_hash.

Now we get to see how/if it's used. There's always 3.0 if it turns out to be not quite right.

Congrats and thanks for your first patch, @qrazhan!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants