比较两个Ruby哈希的值

时间:2017-07-15 15:17:25

标签: ruby hash compare

我正在处理一个需要比较两个哈希值内的值的项目。哈希键'标题'有一个数组作为其值,其中包含两个问题的标题。 我想要实现的是,如果在issue_yaml中的标题存在于fwparse_issues中,则将标题保存在issue_yaml(哈希中的数组)中,否则删除它'。

示例代码:

  fwparse_issues = [
  {:section_title=>"Security Audit",
  :ref=>"FILTER.LOG.DROP",
  :title=>"Filter Drop Rules Were Configured Without Logging"},
 {:section_title=>"Security Audit",
  :ref=>"LOGGING.SYSLOG.NO.ENCRYPTION",
  :title=>"Syslog Logging Configured With No Encryption"},
 {:section_title=>"Security Audit",
  :ref=>"FILTER.RULE.EENE",
  :title=>"Filter Rules Allow Packets To A Network Destination"},
 {:section_title=>"Security Audit",
  :ref=>"FILTER.RULE.EEER",
  :title=>"Filter Rules Allow Packets To A Port Range"},
 {:section_title=>"Security Audit",
  :ref=>"BANNER.NO.POST.LOGON.MESSAGE",
  :title=>"No Post Logon Banner Message"},
 {:section_title=>"Security Audit",
  :ref=>"LOGGING.SYSLOG.SEVERITY",
  :title=>"Weak Syslog Severity Level Configured"},
 {:section_title=>"Security Audit",
  :ref=>"FILTER.RULE.NEEE",
  :title=>"Filter Rules Allow Packets From A Network Source"}]

issue_yaml = {"ABC-1234"=>
  {"title"=>["No Pre-Logon Banner Message", "No Post Logon Banner Message"],
   "desc"=>"some text",
   "rec"=>"recommendations go here",
   "ref"=>"references"},
 "ABC-5678"=>
  {"title"=>"SSH Protocol Version 1 Supported",
   "desc"=>"some text\nwhich spans\nmultiple lines\n",
   "rec"=>"recommendations go here",
   "ref"=>"references"}}

    fwparse_issues.each do |issue|
      issue_yaml.keys.each do |key|
        if issue_yaml[key]["title"].is_a?(Array)
          unless issue_yaml[key]["title"].include?(issue[:title])
            issue_yaml[key]["title"].delete(issue[:title])
          end
        end 
      end
    end

我最终需要的是:

{"ABC-1234"=>
  **{"title"=>["No Post Logon Banner Message"],**
   "desc"=>"some text",
   "rec"=>"recommendations go here",
   "ref"=>"references"}}

但相反,粗线最终成为:

{"ABC-1234"=>
  {"title"=>["No Pre-Logon Banner Message", "No Post Logon Banner Message"],
   "desc"=>"some text",
   "rec"=>"recommendations go here",
   "ref"=>"references"},

本质上,除非比特不起作用。我花了这么长时间看待它的那种情况之一我甚至不能再思考了。如果我改变了'除非'如果'如果'它会删除"没有后登录横幅消息"来自issue_yaml所以反过来似乎有效!

编辑 更正了预期的输出!

2 个答案:

答案 0 :(得分:0)

这应该可以满足您的需求。

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

public class SearchThroughCards : MonoBehaviour {
    public int size;
    // Use this for initialization
    void Start () {
        StartCoroutine(GetCards());

    }

    // Update is called once per frame
    IEnumerator GetCards()
    {
        UnityWebRequest www = UnityWebRequest.Get("https://www.ygohub.com/api/all_cards");
        yield return www.Send();

        if (www.isNetworkError)
        {
            Debug.Log(www.error);
        }
        else
        {
            // Show results as text
            Debug.Log(www.downloadHandler.text);
            RootCardList cardList = JsonUtility.FromJson<RootCardList>(www.downloadHandler.text);
            size = cardList.card.Count;
            Debug.Log(cardList.card);
            foreach (string str in cardList.card)
            {
                Debug.Log(str);
            }
        }


    }
}

编辑:改为使用就地回答。

哪个收益率:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class RootCardList
{
    public string status;
    public List<string> card;
} 

答案 1 :(得分:0)

假设fwparse_issues在示例中给出,issue_yaml定义如下。

issue_yaml =
  {"ABC-1234"=>
     {"title"=>["No Pre-Logon Banner Message",
                "No Post Logon Banner Message"],
      "desc"=>"some text",
      "rec"=>"recommendations go here",
      "ref"=>"references"},
   "ABC-5678"=>
     {"title"=>"SSH Protocol Version 1 Supported",
      "desc"=>"some text\nwhich spans\nmultiple lines\n",
      "rec"=>"recommendations go here",
      "ref"=>"references"},
   "ABC-5679"=>
     {"title"=>"Weak Syslog Severity Level Configured",
      "desc"=>"some text\nwhich spans\nmultiple lines\n",
      "rec"=>"recommendations go here",
      "ref"=>"references"},
   "ABC-1230"=>
     {"title"=>["No Post Logon Banner Message",
                "No Post Logon Banner Message"],
      "desc"=>"some text",
      "rec"=>"recommendations go here",
      "ref"=>"references"}
  }

我们首先从fwparse_issues构建一个标题数组。

titles = fwparse_issues.map { |h| h[:title] }
  #=> ["Filter Drop Rules Were Configured Without Logging",
  #    "Syslog Logging Configured With No Encryption",
  #    "Filter Rules Allow Packets To A Network Destination",
  #    "Filter Rules Allow Packets To A Port Range",
  #    "No Post Logon Banner Message",
  #    "Weak Syslog Severity Level Configured",
  #    "Filter Rules Allow Packets From A Network Source"]

我们现在可以构造所需的哈希值。

issue_yaml.each_with_object({}) do |(k,v),h|
  keepers = [*v["title"]].select { |s| titles.include?(s) }
  h[k] = v.merge("title"=>keepers.size==1 ? keepers.first : keepers) unless keepers.empty?
end
  #=> {"ABC-1234"=>{"title"=>"No Post Logon Banner Message",
  #                 "desc"=>"some text",
  #                 "rec"=>"recommendations go here",
  #                 "ref"=>"references"},
  #    "ABC-5679"=>{"title"=>"Weak Syslog Severity Level Configured",
  #                 "desc"=>"some text\nwhich spans\nmultiple lines\n",
  #                 "rec"=>"recommendations go here", "ref"=>"references"},
  #    "ABC-1230"=>{"title"=>["No Post Logon Banner Message",
  #                           "No Post Logon Banner Message"],
  #                 "desc"=>"some text",
  #                 "rec"=>"recommendations go here",
  #                 "ref"=>"references"}
  #   }

如果s = v["title"]是字符串,则[*v["title"]]会返回[s]。如果arr = v["title"]是数组,则[*v["title"]]会返回v。例如,如果v = "hi"[*v] #=> ['hi'];如果v = ['hi', 'ho'][*v["title"]]返回['hi', 'ho']

让我们更仔细地检查所执行的计算。我们首先创建一个枚举器。

enum = issue_yaml.each_with_object({})
  #=> enum=#<Enumerator:0x00000000e5be38>

我们可以通过将枚举器转换为数组(或执行enum)来检查枚举器enum.entries将生成的值。

enum.to_a
  #=> [[["ABC-1234", {"title"=>["No Pre-Logon Banner Message",
  #                             "No Post Logon Banner Message"],
  #                   "desc" =>"some text",
  #                   "rec"  =>"recommendations go here",
  #                   "ref"  =>"references"}], {}],
  #    [["ABC-5678", {"title"=>"SSH Protocol Version 1 Supported",
  #                   "desc" =>"some text\nwhich spans\nmultiple lines\n",
  #                   "rec"  =>"recommendations go here",
  #                   "ref"  =>"references"}], {}],
  #    [["ABC-5679", {"title"=>"Weak Syslog Severity Level Configured", 
  #                   "desc" =>"some text\nwhich spans\nmultiple lines\n",
  #                   "rec"  =>"recommendations go here",
  #                   "ref"=>"references"}], {}],
  #    [["ABC-1230", {"title"=>["No Post Logon Banner Message",
  #                             "No Post Logon Banner Message"],
  #                   "desc"=>"some text",
  #                   "rec"=>"recommendations go here",
  #                   "ref"=>"references"}], {}]]

enum生成一系列元素,这些元素传递给块并分配给块变量。生成并传递给块的第一个元素如下。

(k,v), h = enum.next
  #=> [["ABC-1234", {"title"=>["No Pre-Logon Banner Message",
  #                            "No Post Logon Banner Message"],
  #                  "desc"=>"some text",
  #                  "rec" =>"recommendations go here",
  #                  "ref" =>"references"}], {}]

Ruby消除了这个数组的歧义,并为块变量赋值。

k #=> ABC-1234
v #=> {"title"=>["No Pre-Logon Banner Message",
  #              "No Post Logon Banner Message"],
  #    "desc"=>"some text", 
  #    "rec" =>"recommendations go here",
  #    "ref"=>"references"}
h #=> {}

我们现在可以执行块计算。

a = v["title"]
  #=> ["No Pre-Logon Banner Message", "No Post Logon Banner Message"]
b = [*a]
  #=> ["No Pre-Logon Banner Message", "No Post Logon Banner Message"]
keepers = b.select { |s| titles.include?(s) }
  #=> ["No Post Logon Banner Message"]
keepers.empty?
  #=> false
keepers.size == 1,
  #=> true
c = keepers.first
  #=> No Post Logon Banner Message
h[k] = v.merge("title"=>c)
  #=> {"title"=>"No Post Logon Banner Message",
  #    "desc"=>"some text",
  #    "rec"=>"recommendations go here", "ref"=>"references"}
h #=> {"ABC-1234"=>{"title"=>"No Post Logon Banner Message",
  #                 "desc" =>"some texte",
  #                 "ref"=>"references"}}

其余的计算方法类似。

创建键"titles"数组(字符串)的所有值可能更方便,即使这些数组只包含一个字符串。