Почему я не могу создать новый хэш из выбранных ключей в ruby? - PullRequest
5 голосов
/ 09 февраля 2012

Это меня давно беспокоило. Это не сложно, но я не знаю, почему уже нет простого способа сделать это, и я держу пари, что есть, и я не вижу этого.

Я просто хочу взять хеш, например:

cars = {:bob => 'Pontiac', :fred => 'Chrysler', 
        :lisa => 'Cadillac', :mary => 'Jaguar'}

и сделайте что-то вроде

cars[:bob, :lisa]

и получите

{:bob => 'Pontiac', :lisa => 'Cadillac'}

Я сделал это, и это прекрасно работает:

class Hash
  def pick(*keys)
    Hash[select { |k, v| keys.include?(k) }]
  end
end

ruby-1.8.7-p249 :008 > cars.pick(:bob, :lisa)
=> {:bob=>"Pontiac", :lisa=>"Cadillac"} 

Очевидно, что существует миллион простых способов сделать это, но мне интересно, есть ли что-то встроенное, что я пропустил, или хорошая неочевидная причина, это не стандартная и нормальная вещь? Без этого я использую что-то вроде:

chosen_cars = {:bob => cars[:bob], :lisa => cars[:lisa]}

что не конец света, но это не очень красиво. Кажется, это должно быть частью обычного словарного запаса. Что мне здесь не хватает?

(связанные вопросы включают в себя: Ruby Hash Whitelist Filter ) (этот пост в блоге имеет тот же результат, что и я, но опять же, почему он не встроен? http://matthewbass.com/2008/06/26/picking-values-from-ruby-hashes/)

Обновление:

Я использую Rails с ActiveSupport :: CoreExtensions :: Hash :: Slice, который работает именно так, как я хочу, поэтому проблема решена, но все же ... может, кто-то другой найдет здесь ответ :)

Ответы [ 5 ]

5 голосов
/ 24 июля 2018

Просто чтобы помочь другим, через несколько лет после факта:

Slice прекрасно работает, чтобы делать то, что я хотел.

> cars.slice(:bob, :lisa)
=> {:bob=>"Pontiac", :lisa=>"Cadillac"} 
4 голосов
/ 09 февраля 2012

Я всегда думал, что это тоже странное упущение, но на самом деле не существует простого, стандартного метода для этого.

Ваш приведенный выше пример может быть излишне медленным, поскольку он перебирает все записи хешанужны они нам или нет, а затем многократно просматривает массив параметров ключей.Этот код должен быть немного быстрее (при условии, что это когда-нибудь будет иметь значение - и я не пытался его тестировать).

class Hash
  def pick(*keys)
    values = values_at(*keys)
    Hash[keys.zip(values)]
  end
end
1 голос
/ 24 марта 2012

select заслуживает, по крайней мере, упоминания:

cars = {:bob => 'Pontiac', :fred => 'Chrysler', 
        :lisa => 'Cadillac', :mary => 'Jaguar'}
people = [:bob, :lisa]

p cars.select{|k, _| people.include?(k)}
#=> {:bob=>"Pontiac", :lisa=>"Cadillac"}
0 голосов
/ 11 декабря 2013
{ height: '178cm', weight: '181lbs', salary: '$2/hour' }.select { |k,v| [:height, :weight].include?(k)  }
0 голосов
/ 09 февраля 2012

Ruby позволяет добавить эту функцию без особых усилий:

class Hash
  alias old_accessor :[]

  def [](*key)
    key.is_a?(Array) ? self.dup.delete_if{|k, v| !key.include? k} : old_accessor(key)
  end
end

Надеюсь, это поможет. Я знаю, что это не встроенная функция.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...