【问题标题】:Ruby - Set key-value pairs inside array of hashesRuby - 在哈希数组中设置键值对
【发布时间】:2019-04-30 10:03:36
【问题描述】:

问题是: 我有方法

def comparison_reporter(list_of_scenarios_results1, list_of_scenarios_results2)
  actual_failed_tests = list_of_scenarios_results2.select {|k,v| v == 'Failed'}
  actual_passed_tests = list_of_scenarios_results2.select {|k,v| v == 'Passed'}
  failed_tests = Array.new(actual_failed_tests.length) { Hash.new }
  failed_tests.each do |hash|
      actual_failed_tests.keys.map {|name| hash["test_name"] = name}
      actual_failed_tests.values.map {|new_status| hash["actual_status"] = new_status}
      list_of_scenarios_results1.values_at(*actual_failed_tests.keys).map {|old_status| hash["previous_status"] = old_status}
  end
  final_result = {
    "passed_tests_count" => list_of_scenarios_results2.select {|k,v| v == 'Passed'}.length,
    "failed_tests_count" => list_of_scenarios_results2.select {|k,v| v == 'Failed'}.length,
    "failed_tests" => failed_tests
  }
  return final_result
end

此方法将 2 个哈希值作为参数,并返回它们的比较结果和其他一些内容。目前,它总是返回 failed_tests 并带有两个(或更多)相同的哈希值(相同的键值对)。 我认为,这个问题在failed_tests.each do |hash| 块中的某个地方,但我找不到这个错误的原因,请指教。方法结果示例(.json格式)

{
  "passed_tests_count": 3,
  "failed_tests_count": 2,
  "failed_tests": [
    {
      "test_name": "As a user I want to use Recent searches tab",
      "actual_status": "Failed",
      "previous_status": "Failed"
    },
    {
      "test_name": "As a user I want to use Recent searches tab",
      "actual_status": "Failed",
      "previous_status": "Failed"
    }
  ]
}

更新: hash1(第一个参数) -

{""=>"Passed",
"As a new user I want to use no fee rentals tab"=>"Passed",
"As a new user I want to use Luxury rentals tab"=>"Passed", 
"As a user I want to use Recent searches tab"=>"Failed",
"As a user I want to use new listings for you tab"=>"Passed"}

hash2(第二个参数)-

{""=>"Passed",
"As a new user I want to use no fee rentals tab"=>"Failed",
"As a new user I want to use Luxury rentals tab"=>"Passed",
"As a user I want to use Recent searches tab"=>"Failed",
"As a user I want to use new listings for you tab"=>"Passed"}

所需输出的示例:

{ 
"passed":"count",
"failed":"count",
"failed_tests": [
   {"test_name":"As a user I want to use Recent searches tab",
    "actual_status":"failed",
    "previous_status":"failed"},
   {"test_name":"As a new user I want to use no fee rentals tab",
    "actual_status":"failed",
    "previous_status":"passed"}]
}

【问题讨论】:

  • 您在failed_tests.each do |hash| 块中的某个地方有什么问题?你没有说出来。您希望该方法做什么?
  • 是的,对不起。该方法应返回final_result,其中还应包含failed_tests 具有2 个不同哈希值的数组(不同测试的结果和比较)。目前,正如您从示例中看到的那样 - 两个哈希实际上是相同的,因此我认为 smthn 在failed_tests.each do |hash| 中是错误的
  • @Mikhah 很高兴你表现出努力,但很难读懂你的方法。如果您想要答案,请提供您的输入(2 个哈希)和您希望成为结果的哈希。
  • @sawa ofc,我已经更新了问题
  • @MarcinKołodziej 抱歉,点击错误)我已经更新了问题

标签: arrays ruby iterator ruby-hash


【解决方案1】:

解决办法:

def comparison_reporter(before, after)
  failed_tests = after.select { |k,v| v == "Failed" }.map do |k,v|
    {
      test_name: k,
      actual_status: v,
      previous_status: before[k]
    }
  end

  {
    passed: after.size - failed_tests.size,
    failed: failed_tests.size,
    failed_tests: failed_tests
  }
end

简化了failed_tests。由于我们计算了失败测试的数量,我们可以将其用于最终计数,而不是再次迭代哈希。

【讨论】:

  • 感谢您的简化和回答,效果很好)
  • 也许...after.each_with_object([]) { |(k,v),a| a << { test_name: k,actual_status: v, previous_status: before[k] } if v=="Failed" } 只遍历数组一次。
【解决方案2】:

问题出在第 8 行:当您映射 hash["previous_status"] 时,您正在用 list_of_scenarios_results1.values_at(*actual_failed_tests.keys) 中的最后一个值覆盖它。

通常您使用 map 将可迭代对象分配给某些内容,而不是修改其他内容。 例如
x = ['1','2','3'].map(&:to_i)
而不是
x = []; ['1','2','3'].map {|v| x << v.to_i}

我建议重新考虑您的方法。你会在两个哈希中总是有相同的键吗?如果是这样,您可以简化这一点。我还建议调查byebug。它是一个交互式调试器,可让您单步执行您的函数并查看哪些地方没有按照您的预期进行。

【讨论】:

  • 感谢您的建议,我以后一定会使用 byebug
猜你喜欢
  • 2015-03-28
  • 2021-02-05
  • 2016-02-05
  • 1970-01-01
  • 1970-01-01
  • 2015-04-19
  • 1970-01-01
  • 2014-01-02
  • 1970-01-01
相关资源
最近更新 更多