如何做哈希算法

时间:2014-02-13 02:46:43

标签: ruby hash

我想从哈希中的startOn时间减去ackedOns时间,以获取确认警报所花费的纪元秒数。

以下是代码:

url = "https://xyz"
uri = URI(url)
http = Net::HTTP.new(uri.host, 443)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
req = Net::HTTP::Get.new(uri.request_uri)
response = http.request(req)
jsonResponse = JSON.parse(response.body)
#troubelshooting step to see how many total alerts there are
total = jsonResponse['data']['total']
pp total

# create the collected_alerts hash
collected_alerts = { 'hosts'=> [],'dataPoints' => [], 'startOns' => [], 'ackedOns' => [], 'timeToAcks' => []  }

# iterate through the json
jsonResponse['data']['alerts'].each do |alerts|
   # store the interested json values into the appropriate hash
   collected_alerts['hosts'] << alerts['host']
   collected_alerts['dataPoints'] << alerts['dataPoint']
   collected_alerts['startOns'] << alerts['startOn']
   collected_alerts['ackedOns'] << alerts['ackedOn']

   # Calculate mins it took to acknowledge alert and store it in timeToAcks
   # Formula is Ack time - Start time which would give us seconds / 60 to give mins.             
   alerts['timeToAcks'] = alerts['ackedOn'].zip(alerts['startOn']).map{|a,s| a-s/60}    
end
pp collected_alerts

CSV.open("data.csv", "wb") {|csv| collected_alerts.to_a.each {|elem| csv << elem} }

这是我试图解析的json响应

{
  "status": 200,
  "data": {
    "total": 3,
    "alerts": [
      {
        "dataPoint": "average",
        "ackedBy": "x",
        "dataSourceInstance": "Ping50Packets",
        "dataSource": "Ping50Packets",
        "host": "x",
        "endOn": 0,
        "ackedOn": 1392218853,
        "dataSourceInstanceId": 400554,
        "hostId": 1829,
        "type": "alert",
        "dataSourceId": 560,
        "ackedOnLocal": "2014-02-12 07:27:33 PST",
        "id": 6862895,
        "startOn": 1392197595,
        "thresholds": "> 200",
        "endOnLocal": "",
        "level": "warn",
        "ackComment": "Ack.",
        "value": "206.00",
        "hostDataSourceId": 137481,
        "acked": true,
        "hostGroups": [{
          "alertEnable": true,
          "createdOn": 1367604091,
          "id": 106,
          "parentId": 105,
          "description": "",
          "appliesTo": "",
          "name": "x",
          "fullPath": "x"
        }],
        "startOnLocal": "2014-02-12 01:33:15 PST"
      },

2 个答案:

答案 0 :(得分:1)

像某样的东西;

 alerts['tta'] = alerts['ackedOns'].zip(alerts['startOns']).map{|a,s| a-s/60}

答案 1 :(得分:0)

根据您的数据,您只需执行以下操作:

collected_alerts['timeToAcks'] << (alerts['ackedOn'] - alerts['startOn'])/60
  • 您的原始代码在其中一个字段名称中出现拼写错误。
  • 您想将这些值推送到collected_alerts,而不是当前的alert,对吧?

或者,在您完成所有警报之后:

ca = collected_alerts
ca['timeToAcks'] = ca['ackedOns'].zip(ca['startOns']).map{ |ack,st| (ack-st)/60 }

此外,我不是一次一个地循环播放警报并拔出碎片,而是执行此操作:

alerts = jsonResponse['data']['alerts']
collected_alerts = {}
%w[host dataPoint startOn ackedOn].each do |field|
  collected_alerts[field] = alerts.map{ |alert| alert[field] }
end

甚至更好:

alert_fields = %w[host dataPoint startOn ackedOn]
collected_alerts = Hash[ alert_fields.map{ |f| [f,alerts.map{|a| a[f] }] } ]

大致按执行顺序解释。

  • alert_fields = %w[ … ] - 创建一个引用字符串值数组的变量(在源代码中以空格分隔),即["ackedOn", "host", … ]
  • alerts.map{ |a| … } - 通过获取alerts数组中的每个值创建一个新数组,创建一个引用该值的名为a的变量,并使用块的结果作为值在新阵列中。
    • a[f] - 对于alerts数组中的每个提醒,请使用值f查找密钥。例如,当f"ackedOn"时,会查找a["ackedOn"]的值。
  • alert_fields.map{ |f| … } - 对于数组中的每个元素,创建一个名为f的变量(对于'field')并运行该块的内容。创建一个新数组,其中内容为每个条目,无论块的最终值是什么。
    • [f, … ] - 在为所有警报中的特定字段创建所有值的数组之后,此块的结果是一个双元素数组,该字段的名称后跟这些值。例如,[ "ackedOn", [1,3,16,4,44,7] ]
  • Hash[ … ] - 给定一个二值数组的数组,创建一个哈希映射,将每对中的第一个值映射到第二个值,即{ "ackedOn" => [1,3,16,4,44,7] }
    • 同样的Hash[…]方法可选择接受偶数个参数,将每个偶数参数与下一个参数配对。

举例:

alert_fields = %w[ackedOn host dataPoint startOn]
#=> ["ackedOn", "host", "dataPoint", "startOn" ]

alerts.map{|a| a[f] }
#=> [5,3,4,5,1,6,8,2,…]

[f,alerts.map{|a| a[f] }]
#=> ["ackedOn",[5,3,4,5,1,6,8,2,…]]

alert_fields.map{ |f| [f,alerts.map{|a| a[f] }] }
#=> [
#=>   ["host",['foo','bar',…]], 
#=>   …
#=>   ["ackedOn",[5,3,4,5,1,6,8,2,…]]
#=> ]

Hash[ alert_fields.map{ |f| [f,alerts.map{|a| a[f] }] } ]
#=> {
#=>   "host" => ['foo','bar',…], 
#=>   …
#=>   "ackedOn" => [5,3,4,5,1,6,8,2,…]
#=> }