使用 Ruby 搜索 JSON 响应并计数出现次数



我今天似乎无法解决以下问题。我正在解析来自 API 的 JSON 响应,该响应可帮助我计划我的物品将填满多少箱子以完成货件。

我已经将 API 中的 JSON 响应保存并解析为下面的 Rails 中名为API_response的变量。现在,我特别需要计算每次"id"=>"Bin1"出现在此响应中的时间。

我在想也许最好的方法是为"id"=>"Bin1"做一个选择,每次都将其映射到一个数组,然后计算数组中的索引数,以便我最终计算我将使用多少个盒子?我将如何做到这一点?

API_response = {"response"=>{"id"=>"1538005707_bc789275d7cc93eca86830e41a44f7a9", "bins_packed"=>[{"bin_data"=>{"w"=>12, "h"=>6, "d"=>12, "id"=>"Bin1", "used_space"=>57.8704, "weight"=>80, "used_weight"=>100, "stack_height"=>5, "order_id"=>"unknown"}, "items"=>[{"id"=>12, "w"=>10, "h"=>5, "d"=>10, "wg"=>80}]}, {"bin_data"=>{"w"=>12, "h"=>6, "d"=>12, "id"=>"Bin1", "used_space"=>57.8704, "weight"=>80, "used_weight"=>100, "stack_height"=>5, "order_id"=>"unknown"}, "items"=>[{"id"=>12, "w"=>10, "h"=>5, "d"=>10, "wg"=>80}]}, {"bin_data"=>{"w"=>12, "h"=>6, "d"=>12, "id"=>"Bin1", "used_space"=>57.8704, "weight"=>80, "used_weight"=>100, "stack_height"=>5, "order_id"=>"unknown"}, "items"=>[{"id"=>12, "w"=>10, "h"=>5, "d"=>10, "wg"=>80}]}], "errors"=>[], "status"=>1, "not_packed_items"=>[]}}

更新 我想我真正想做的是,对于每次出现 Bin1,将 bin 的权重推到一个新的数组中。所以我希望上面响应示例中的最终结果是一个数组,例如Bin1_Array = [80, 80, 80]

假设您只需要示例的数字3

API_response["response"]["bins_packed"].count do |item| 
item["bin_data"]["id"] == "Bin1"
end

编辑评论中的其他问题:

API_response["response"]["bins_packed"].each_with_object([]) do |item, arr|
arr << item["bin_data"]["weight"] if item["bin_data"]["id"] == "Bin1"
end

这与Marcin Kolodziej的答案相同,只是请注意,如果您将with_indifferent_access标记到API_response的末尾,如下所示:

API_response = {
"response"=>{
...
}
}.with_indifferent_access

然后你可以使用符号而不是字符串作为你的键(我倾向于这样做(,如下所示:

API_response[:response][:bins_packed].count do |item|
item[:bin_data][:id] == "Bin1"
end

如果你不喜欢所有这些括号(我倾向于不喜欢,因为它会减慢我的打字速度(,你可以这样做:

API_response.dig(:response, :bins_packed).count do |item|
item.dig(:bin_data, :id) == "Bin1"
end

如果由于某种原因您可能缺少 :response 或 :bins_packed 的键(在这种情况下,dig将返回nil并且.count会抛出错误(,您可以这样做

(API_response.dig(:response, :bins_packed) || []).count do |item|
item.dig(:bin_data, :id) == "Bin1"
end

在缺少密钥的情况下,这将返回0。这似乎不太可能,但我想无论如何我都会提到它。

你可以试试这个:

API_response["response"]["bins_packed"].group_by{|x| x["bin_data"]["id"]}["Bin1"].count

在这里,group_by将对 ["bin_data"]["id"] 的元素进行分组,一旦我们分组,我们就可以轻松获得特定键的组计数。

最新更新