2016-06-08 8 views
0

Я новичок в рубине, поэтому, пожалуйста, извините за любое незнание, которое я могу нести. Мне было интересно, как разбирать ответ JSON для каждого значения, принадлежащего определенному ключу. Ответ в формате,Ruby, Разбор JSON-ответа для массива значений

[ 
    { 
    "id": 10008, 
    "name": "vpop-fms-inventory-ws-client", 
    "msr": [ 
     { 
     "key": "blocker_violations", 
     "val": 0, 
     "frmt_val": "0" 
     }, 
    ] 
    }, 
    { 
    "id": 10422, 
    "name": "websample Maven Webapp", 
    "msr": [ 
     { 
     "key": "blocker_violations", 
     "val": 0, 
     "frmt_val": "0" 
     }... 

Там в некоторых других записей в ответ, но ради не имея огромный блок кода, Я сократил it.The код, который я написал это:

require 'uri' 
require 'net/http' 
require 'JSON' 
url = URI({my url}) 

    http = Net::HTTP.new(url.host, url.port) 

    request = Net::HTTP::Get.new(url) 
    request["cache-control"] = 'no-cache' 
    request["postman-token"] = '69430784-307c-ea1f-a488-a96cdc39e504' 

    response = http.request(request) 
    parsed = response.read_body 

    h = JSON.parse(parsed) 

    num = h["msr"].find {|h1| h1['key']=='blocker_violations'}['val'] 

Я по существу ищу значение val для каждого нарушения блокировки (ответ json содержит сотни записей, поэтому im ожидает сотни значений блокировщика). Я надеялся, что num будет содержать массив всех «val». Если у вас есть какие-либо идеи в этом, это будет очень полезно!

EDIT! Я получаю выход консольной

scheduler caught exception: 
no implicit conversion of String into Integer 
C:/dashing/test_board/jobs/issue_types.rb:20:in `[]' 
C:/dashing/test_board/jobs/issue_types.rb:20:in `block (2 levels) in <top (requi 
red)>' 
C:/dashing/test_board/jobs/issue_types.rb:20:in `select' 

я подозреваю, что может быть слишком много, чтобы сделать с вопросом, но какая-то помощь будет оценен по достоинству!

+0

Вам нужно перебрать массив объектов, а затем перебрать массив 'msr', ищет каждый «ключ», который соответствует. –

ответ

1

Вам нужно сделать 2 вещи. Во-первых, вам возвращается массив, и вас интересует только подмножество элементов. Это общий шаблон, который решается фильтром, или select в Ruby. Во-вторых, условие, по которому вы хотите выбрать эти элементы, также зависит от значений другого массива, которые необходимо фильтровать с использованием другой техники. Вы можете попытаться сделать это так:

res = [ 
    { 
    "id": 10008, 
    "name": "vpop-fms-inventory-ws-client", 
    "msr": [ 
     { 
     "key": "blocker_violations", 
     "val": 123, 
     "frmt_val": "0" 
     } 
    ] 
    }, 
    { 
    "id": 10008, 
    "name": "vpop-fms-inventory-ws-client", 
    "msr": [ 
     { 
     "key": "safe", 
     "val": 0, 
     "frmt_val": "0" 
     } 
    ] 
    } 
] 

# define a lambda function that we will use later on to filter out the blocker violations 
violation = -> (h) { h[:key] == 'blocker_violations' } 

# Select only those objects who contain any msr with a key of  blocker_violations 
violations = res.select {|h1| h1[:msr].any? &violation } 

# Which msr value should we take? Here I just take the first. 
values = violations.map {|v| v[:msr].first[:val] } 

Проблема вы можете иметь с этим кодом, что msr является массивом. Таким образом, теоретически, вы можете получить 2 объекта в msr, который является нарушением блокатора, а другой - нет. Вы должны решить, как вы справляетесь с этим. В моем примере я включаю его, если он имеет одно нарушение блокировки с использованием any?. Однако вы можете включить их только в том случае, если все объекты msr являются нарушениями блокировщика. Вы можете сделать это с помощью метода all?.

Вторая проблема, с которой вы сталкиваетесь, - это какое значение для возврата? Если в объекте msr есть несколько нарушений блокировки, какое значение вы выберете? Я только что взял first, но это может не сработать для вас.

В зависимости от ваших требований мой пример может работать, или вам может понадобиться его адаптировать.

Кроме того, если вы никогда не сталкивались с синтаксисом лямбда раньше, вы можете прочитать больше об этом here

+0

Не предлагая, чтобы ваше предложение было неправильным, но я думаю, что у меня есть еще одна ошибка, которая мешает мне проверить, работает ли этот способ. Надеюсь, я смогу вернуться к этому. –

+0

Нет, ты прав. Мой ответ не будет работать как 'msr' - это массив, а не хэш. Я уточню с лучшим ответом. – MrWillihog

+0

Да! это именно то, что мне нужно, с его помощью. Спасибо огромное! Просто выполните следующие действия: как сделать это так: res = h или какой-либо другой 'res =', так что res является массивом, содержащим весь api-вызов, а не строку (?), Иначе функция 'any?' Выиграла Не работай. –