2015-01-05 3 views
0

Мне нужно получить некоторую информацию, связанную с фильмами и шоу из документа json.Избегайте вложенных блоков выбора

unique_nos = js['navigation']['category'].select{|n| n['name']=="Home"}.first['category'].select{|s| s['name']=="#{type}"}.first['category'].select{|k| k['name']=='Movie Studios'}.first['category'].map{|l| l['categoryId']} 

То же самое можно сказать и о телешоу.

unique_nos = js['navigation']['category'].select{|n| n['name']=="Home"}.first['category'].select{|s| s['name']=='TV'}.first['category'].select{|k| k['name']=='Networks'}.first['category'].map{|l| l['categoryId']} 

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

+0

Можете ли вы опубликовать json fragement? –

+0

Не могли бы вы просто создать метод 'unique_nos', который будет называться' unique_nos (js, "# {type}", "Movie Studios") 'в первом примере и' unique_nos (js, "TV", "Networks") 'во втором? (Я вижу из ответа @ Uri, что мы думаем по тем же линиям, а также что я забыл аргумент 'js'.) –

+0

То, что у вас есть, это цепочки, а не вложенность. – sawa

ответ

2

Вы можете просто извлечь его как метод:

def find_unique_nos(js, type, category) 
    js['navigation']['category'].select{|n| n['name']=="Home"}.first['category'].select{|s| s['name']== type }.first['category'].select{|k| k['name']==category}.first['category'].map{|l| l['categoryId']} 
end 

На стороне записки, select { ... }.first эквивалентно find { ... }, так что вы можете упростить это:

def find_unique_nos(js, type, category) 
    js['navigation']['category'].find{|n| n['name'] == "Home" }['category'] 
           .find{|s| s['name'] == type }['category'] 
           .find{|k| k['name'] == category }['category'] 
           .map{|l| l['categoryId']} 
end 

Если вы хотите быть более сложный, вы можете использовать строитель для выполнения повторяющегося задания find{ ... }['category']:

def find_unique_nos(js, type, category) 
    ['Home', type, category].inject(js['navigation']['category']) do |cat, name| 
    cat.find{|n| n['name'] == name }['category'] 
    end.map{|l| l['categoryId']} 
end 
0

Пожалуйста, обратите внимание, чтобы использовать промежуточные переменные для разрушения таких длинных цепей, это облегчит отладку и понимание. Используя тот же код с переформатированием:

def unique_numbers(json: j, type: t) 
    category = type == 'TV' ? 'Networks' : 'Movie Studios' 
    json['navigation']['category'] 
    .select{|n| n['name']=="Home"} 
    .first['category'] 
    .select{|s| s['name'] == type } 
    .first['category'] 
    .select{|k| k['name'] == category } 
    .first['category'] 
    .map{|l| l['categoryId']} 
end 
Смежные вопросы