http://qs321.pair.com?node_id=1187120


in reply to Why does ‘keys’ need a named hash?

Actually, if you squint, you would indeed expect keys to return all elements with even index in a list. Similarly, values on a list should return all odd elements. That's how you make a hash: even elements become keys, odd elements become values. I can think of a couple uses cases for this DWIM behaviour that don't involve hashes...

Replies are listed 'Best First'.
Re^2: Why does 'keys' need a named hash?
by dsheroh (Monsignor) on Apr 06, 2017 at 07:39 UTC
    Erm, no, I wouldn't expect that. A hash isn't just an even-sized list. It uses a hashing algorithm (hence the name "hash") to divide the data up into a series of arbitrarily-ordered buckets. The resulting data structure is almost completely unlike a list. Why would functions designed to work on such a structure also work on lists?

    The only way I can squint hard enough at it to make keys work on a list would be if keys operated by flattening the hash into a list and then iterating over every other list element. And I can't for the life of me come up with a good reason for making keys work that way.

    If there really are that many use cases for iterating every other element of a list, they would be much better served by adding a new keyword for that functionality than by bloating keys with an unnecessary and anti-performant hash-to-list conversion, particularly since the new keyword could be generalized to iterate over every Nth element of the list instead of only giving "even elements" and "odd elements" options.

Re^2: Why does 'keys' need a named hash?
by Anonymous Monk on Apr 06, 2017 at 02:09 UTC
    That breaks down if your list has duplicate "keys".
Re^2: Why does 'keys' need a named hash?
by vrk (Chaplain) on May 22, 2017 at 08:45 UTC

    I just noticed there are functions for this in List::Util: pairkeys and pairvalues. For example:

    use v5.14; use List::Util qw(pairkeys pairvalues); my @a = qw(a b c d e f); say "keys = ", join ", ", pairkeys @a; say "values = ", join ", ", pairvalues @a; my %h = @a; say "keys = ", join ", ", keys %h; say "values = ", join ", ", values %h;

    The obvious difference to keys and values of a hash is that pairkeys doesn't remove duplicates and it keeps the original array order.