Project

General

Profile

Actions

Feature #16739

open

Allow Hash#keys and Hash#values to accept a block for filtering output

Added by jacobevelyn (Jacob Evelyn) about 1 year ago. Updated 11 months ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:97588]

Description

I often see code like the following:

hash.select { |_, v| v == :some_value }.keys
hash.keys.select { |k| k.nil? || k.even? }
hash.select { |k, v| valid_key?(k) && valid_value?(v) }.values

Each of these code snippets must allocate an intermediate data structure. I propose allowing Hash#keys and Hash#values to accept optional block parameters that take both key and value. For example, the above code could be rewritten as:

hash.keys { |_, v| v == :some_value }
hash.keys { |k, _| k.nil? || k.even? }
hash.values { |k, v| valid_key?(k) && valid_value?(v) }

This behavior:

  1. Does not break any existing code (since Hash#keys and Hash#values do not currently accept blocks).
  2. Is very readable—it's obvious what it does at a glance.
  3. Is more efficient than current alternatives.
  4. Is more concise than current alternatives.
  5. Is flexible and useful in a variety of scenarios, because the block has access to both key and value (unlike the behavior proposed in #14788).
Actions

Also available in: Atom PDF