简体   繁体   中英

How to iterate hash elements in groups?

I have a hash very similar to the following JSON object; This is only an example not the exact output.

I need to iterate over the hash and sort it by host or by service_name and then output in the view I am working with blocks reflecting those sorts.

If I go to my view expecting to see things listed by host, and I got ten services across that one host, I need to have a list on the view with that per host. Similarly, when it comes to service_name .

If I have 100 service_names matching, I need to block them and list them together.

I am new to Rails, and typically would handle this via JavaScript and JSON as what's being done is ultimately planned for heavy DOM manipulation anyway, but the lead guy insists this has to be done server-side first, so I am at a loss.

{
    "status": "successful",
    "service_list": [
        {
            "service_name": "oozie",
            "status": "RUNNING",
            "status_message": "Running Master Service",
            "host": "1"
        },
        {
            "service_name": "single-namenode",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "single-database",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "datanode",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "secondarynamenode",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "web",
            "status": "DEAD",
            "status_message": "Running Master Service",
            "host": "1"
        },
        {
            "service_name": "tasktracker",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "jobtracker",
            "status": "RUNNING",
            "status_message": "Running Master Service",
            "host": "1"
        },
        {
            "service_name": "oozie",
            "status": "RUNNING",
            "status_message": "Running Master Service",
            "host": "1"
        },
        {
            "service_name": "single-namenode",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "single-database",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "datanode",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "secondarynamenode",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "web",
            "status": "DEAD",
            "status_message": "Running Master Service",
            "host": "1"
        },
        {
            "service_name": "tasktracker",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "jobtracker",
            "status": "RUNNING",
            "status_message": "Running Master Service",
            "host": "1"
        },
        {
            "service_name": "oozie",
            "status": "RUNNING",
            "status_message": "Running Master Service",
            "host": "1"
        },
        {
            "service_name": "single-namenode",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "single-database",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "datanode",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "secondarynamenode",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "web",
            "status": "DEAD",
            "status_message": "Running Master Service",
            "host": "1"
        },
        {
            "service_name": "tasktracker",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "jobtracker",
            "status": "RUNNING",
            "status_message": "Running Master Service",
            "host": "1"
        },
        {
            "service_name": "oozie",
            "status": "RUNNING",
            "status_message": "Running Master Service",
            "host": "1"
        },
        {
            "service_name": "single-namenode",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "single-database",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "datanode",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "secondarynamenode",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "web",
            "status": "DEAD",
            "status_message": "Running Master Service",
            "host": "1"
        },
        {
            "service_name": "tasktracker",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "jobtracker",
            "status": "RUNNING",
            "status_message": "Running Master Service",
            "host": "1"
        },
        {
            "service_name": "oozie",
            "status": "RUNNING",
            "status_message": "Running Master Service",
            "host": "1"
        },
        {
            "service_name": "single-namenode",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "single-database",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "datanode",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "secondarynamenode",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "web",
            "status": "DEAD",
            "status_message": "Running Master Service",
            "host": "1"
        },
        {
            "service_name": "tasktracker",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "jobtracker",
            "status": "RUNNING",
            "status_message": "Running Master Service",
            "host": "1"
        },
        {
            "service_name": "oozie",
            "status": "RUNNING",
            "status_message": "Running Master Service",
            "host": "1"
        },
        {
            "service_name": "single-namenode",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "single-database",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "datanode",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "secondarynamenode",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "web",
            "status": "DEAD",
            "status_message": "Running Master Service",
            "host": "1"
        },
        {
            "service_name": "tasktracker",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "jobtracker",
            "status": "RUNNING",
            "status_message": "Running Master Service",
            "host": "1"
        },
        {
            "service_name": "oozie",
            "status": "RUNNING",
            "status_message": "Running Master Service",
            "host": "1"
        },
        {
            "service_name": "single-namenode",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "single-database",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "datanode",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "secondarynamenode",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "web",
            "status": "DEAD",
            "status_message": "Running Master Service",
            "host": "1"
        },
        {
            "service_name": "tasktracker",
            "status": "RUNNING",
            "status_message": "Running Service",
            "host": "1"
        },
        {
            "service_name": "jobtracker",
            "status": "RUNNING",
            "status_message": "Running Master Service",
            "host": "1"
        }
    ]
}

Here's the code for grouping them by service_name with textual (not HTML) output. HTML would be the same, but with reasonable HTML markup. Service names are sorted alphabetically; no reason other than as an example.

svcs = val[:service_list]
puts "#{svcs.size} service entries."

grouped = svcs.group_by { |svc| svc[:service_name] }
puts "#{grouped.size} named services:"

grouped.keys.sort.each do |name|
    puts "  service: #{name}"
    grouped[name].each do |svc|
        puts "     host: #{svc[:host]}"
        puts "   status: #{svc[:status]}"
        puts "           #{svc[:status_message]}"
    end
    puts '-'*40
end

group_by returns a hash of arrays, keyed (in this case) by the service_name string (eg, "web" , "tasktracker" , etc.) If you need to sort within each group's info, use sort . For example, to sort within each group by the :status value:

grouped.keys.sort.each do |name|
    puts "  service: #{name}"
    group_info = grouped[name]
    sorted_info = group_info.sort { |a, b| a[:status] <=> b[:status] }
    sorted_info.each do |svc|
        puts "     host: #{svc[:host]}"
        puts "   status: #{svc[:status]}"
        puts "           #{svc[:status_message]}"
    end
    puts '-'*40
end

You can also save the sorting methods for later use:

sort_by_status = Proc.new { |a, b| a[:status] <=> b[:status] }
sorted_info = group_info.sort &sort_by_status   

Here's the JSON converted to a Ruby hash in case you need it.

val = {
    :status => "successful",
    :service_list => [
        {
            :service_name => "oozie",
            :status => "RUNNING",
            :status_message => "Running Master Service",
            :host => "1"
        },
        {
            :service_name => "single-namenode",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "single-database",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "datanode",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "secondarynamenode",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "web",
            :status => "DEAD",
            :status_message => "Running Master Service",
            :host => "1"
        },
        {
            :service_name => "tasktracker",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "jobtracker",
            :status => "RUNNING",
            :status_message => "Running Master Service",
            :host => "1"
        },
        {
            :service_name => "oozie",
            :status => "RUNNING",
            :status_message => "Running Master Service",
            :host => "1"
        },
        {
            :service_name => "single-namenode",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "single-database",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "datanode",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "secondarynamenode",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "web",
            :status => "DEAD",
            :status_message => "Running Master Service",
            :host => "1"
        },
        {
            :service_name => "tasktracker",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "jobtracker",
            :status => "RUNNING",
            :status_message => "Running Master Service",
            :host => "1"
        },
        {
            :service_name => "oozie",
            :status => "RUNNING",
            :status_message => "Running Master Service",
            :host => "1"
        },
        {
            :service_name => "single-namenode",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "single-database",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "datanode",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "secondarynamenode",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "web",
            :status => "DEAD",
            :status_message => "Running Master Service",
            :host => "1"
        },
        {
            :service_name => "tasktracker",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "jobtracker",
            :status => "RUNNING",
            :status_message => "Running Master Service",
            :host => "1"
        },
        {
            :service_name => "oozie",
            :status => "RUNNING",
            :status_message => "Running Master Service",
            :host => "1"
        },
        {
            :service_name => "single-namenode",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "single-database",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "datanode",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "secondarynamenode",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "web",
            :status => "DEAD",
            :status_message => "Running Master Service",
            :host => "1"
        },
        {
            :service_name => "tasktracker",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "jobtracker",
            :status => "RUNNING",
            :status_message => "Running Master Service",
            :host => "1"
        },
        {
            :service_name => "oozie",
            :status => "RUNNING",
            :status_message => "Running Master Service",
            :host => "1"
        },
        {
            :service_name => "single-namenode",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "single-database",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "datanode",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "secondarynamenode",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "web",
            :status => "DEAD",
            :status_message => "Running Master Service",
            :host => "1"
        },
        {
            :service_name => "tasktracker",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "jobtracker",
            :status => "RUNNING",
            :status_message => "Running Master Service",
            :host => "1"
        },
        {
            :service_name => "oozie",
            :status => "RUNNING",
            :status_message => "Running Master Service",
            :host => "1"
        },
        {
            :service_name => "single-namenode",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "single-database",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "datanode",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "secondarynamenode",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "web",
            :status => "DEAD",
            :status_message => "Running Master Service",
            :host => "1"
        },
        {
            :service_name => "tasktracker",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "jobtracker",
            :status => "RUNNING",
            :status_message => "Running Master Service",
            :host => "1"
        },
        {
            :service_name => "oozie",
            :status => "RUNNING",
            :status_message => "Running Master Service",
            :host => "1"
        },
        {
            :service_name => "single-namenode",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "single-database",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "datanode",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "secondarynamenode",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "web",
            :status => "DEAD",
            :status_message => "Running Master Service",
            :host => "1"
        },
        {
            :service_name => "tasktracker",
            :status => "RUNNING",
            :status_message => "Running Service",
            :host => "1"
        },
        {
            :service_name => "jobtracker",
            :status => "RUNNING",
            :status_message => "Running Master Service",
            :host => "1"
        }
    ]
}

Use find_all and sort_by .

# Get all the thingies with the service name "web"
thingies.find_all {|thingy| thingy[:service_name] == 'web' }

# Sort all the thingies by status
thingies.sort_by {|thingy| thingy[:status] }

# Put them together
thingies.find_all {|thingy| thingy[:service_name] == 'web' } \
        .sort_by  {|thingy| thingy[:status]}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM