Обратите внимание на различия в массивах — Ruby

#ruby-on-rails #ruby #activerecord

#ruby-on-rails #ruby #activerecord

Вопрос:

У меня есть два массива. Один — это набор навыков, другой — это набор навыков, которые может использовать пользователь. Чтобы проиллюстрировать :

 ['swimming', 'rowing', 'cycling'] is the set of all skills
  

Теперь пользователь может обладать таким набором навыков, как :

 ['rowing', 'cycling']
  

Как я могу создать хороший хэш, который будет отображать, обладает ли пользователь текущим навыком? Например, для этого конкретного пользователя это было бы :

 {'swimming' => no, 'rowing' => yes, 'cycling', => yes}
  

P.S. На самом деле я хочу сделать это с объектами active record в rails, но я полагаю, что это та же идея.

Ответ №1:

Следующее даст true и false вместо yes и no .

 all_skills = %w[swimming rowing cycling]
user_skills = %w[rowing cycling]

Hash[all_skills.map{|k| [k, user_skills.include?(k)]}]
  

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

 Hash[user_skills.map{|k| [k, true]}]}
  

Ответ №2:

Вот один краткий способ сделать это:

 ALL_SPORTS = ['swimming', 'rowing', 'cycling']

user_array = ['rowing', 'cycling']
user_hash = ALL_SPORTS.inject(Hash.new) { |h, sport| {sport => user_array.include?(sport)}.merge(h) }
  

Ответ №3:

Я предполагаю, что когда вы говорите «да» и «нет», вам действительно нужны логические значения. Следующее не использует никаких промежуточных значений и зависит только от определенных пользователем видов спорта:

 > h = Hash.new(false).merge(Hash[%w[rowing swimming].map {|v| [v.to_sym, true]}])
 => {:rowing=>true, :swimming=>true}
  

Теперь, если вы вызовете любой другой вид спорта в качестве ключа, которого нет у пользователя, вы получите желаемый результат:

 > h[:golf]
 => false
  

Это также предполагает, что вам также нужны символы для ключей.