【问题标题】:Find the largest, smallest, and average value for an array of hashes with common keys?找到具有公共键的散列数组的最大值、最小值和平均值?
【发布时间】:2015-12-08 00:37:49
【问题描述】:

我有一个包含以下信息的哈希数组。我试图获得“timeAsleep”的最大、最小和平均值。我已经尝试了这些问题的答案,但它似乎不起作用。

Find the largest value for an array of hashes with common keys?

Finding the element of a Ruby array with the maximum value for a particular attribute

rails select maximum value from array of hash

这是哈希数组

{"id"=>"1", "userId"=>"1", "day"=>"2015-12-05", "startTime"=>"2015-12-05T07:49:30.000Z", "endTime"=>"2015-12-05T15:56:30.000Z", "tzOffset"=>"-08:00", "source"=>"misfit", "mainSleep"=>true, "timeAsleep"=>478, "timeAwake"=>9, "efficiency"=>0, "timeToFallAsleep"=>0, "timeAfterWakeup"=>0, "numberOfWakeups"=>1, "timeInBed"=>0, "createdAt"=>"2015-12-05T21:59:24.935Z", "updatedAt"=>"2015-12-05T21:59:24.935Z", "humanId"=>"1"}
{"id"=>"2", "userId"=>"2", "day"=>"2015-12-04", "startTime"=>"2015-12-04T07:02:30.000Z", "endTime"=>"2015-12-04T14:59:30.000Z", "tzOffset"=>"-08:00", "source"=>"misfit", "mainSleep"=>true, "timeAsleep"=>471, "timeAwake"=>6, "efficiency"=>0, "timeToFallAsleep"=>0, "timeAfterWakeup"=>0, "numberOfWakeups"=>1, "timeInBed"=>0, "createdAt"=>"2015-12-04T16:41:44.198Z", "updatedAt"=>"2015-12-04T16:41:44.198Z", "humanId"=>"2"}
{"id"=>"3", "userId"=>"3", "day"=>"2015-12-03", "startTime"=>"2015-12-03T06:02:32.000Z", "endTime"=>"2015-12-03T13:38:32.000Z", "tzOffset"=>"-08:00", "source"=>"misfit", "mainSleep"=>true, "timeAsleep"=>434, "timeAwake"=>22, "efficiency"=>0, "timeToFallAsleep"=>0, "timeAfterWakeup"=>0, "numberOfWakeups"=>2, "timeInBed"=>0, "createdAt"=>"2015-12-03T15:35:42.903Z", "updatedAt"=>"2015-12-03T15:35:42.903Z", "humanId"=>"3"}
{"id"=>"4", "userId"=>"4", "day"=>"2015-12-02", "startTime"=>"2015-12-02T09:17:33.000Z", "endTime"=>"2015-12-02T15:27:33.000Z", "tzOffset"=>"-08:00", "source"=>"misfit", "mainSleep"=>true, "timeAsleep"=>370, "timeAwake"=>0, "efficiency"=>0, "timeToFallAsleep"=>0, "timeAfterWakeup"=>0, "numberOfWakeups"=>0, "timeInBed"=>0, "createdAt"=>"2015-12-03T04:00:02.050Z", "updatedAt"=>"2015-12-03T04:00:02.050Z", "humanId"=>"4"}
{"id"=>"5", "userId"=>"5", "day"=>"2015-12-01", "startTime"=>"2015-12-01T05:45:36.000Z", "endTime"=>"2015-12-01T13:50:36.000Z", "tzOffset"=>"-08:00", "source"=>"misfit", "mainSleep"=>true, "timeAsleep"=>485, "timeAwake"=>0, "efficiency"=>0, "timeToFallAsleep"=>0, "timeAfterWakeup"=>0, "numberOfWakeups"=>0, "timeInBed"=>0, "createdAt"=>"2015-12-01T17:50:20.168Z", "updatedAt"=>"2015-12-01T17:50:20.168Z", "humanId"=>"5"}
{"id"=>"6", "userId"=>"6", "day"=>"2015-11-30", "startTime"=>"2015-11-30T05:57:38.000Z", "endTime"=>"2015-11-30T14:23:38.000Z", "tzOffset"=>"-08:00", "source"=>"misfit", "mainSleep"=>true, "timeAsleep"=>499, "timeAwake"=>7, "efficiency"=>0, "timeToFallAsleep"=>0, "timeAfterWakeup"=>0, "numberOfWakeups"=>1, "timeInBed"=>0, "createdAt"=>"2015-11-30T16:18:38.276Z", "updatedAt"=>"2015-11-30T16:18:38.276Z", "humanId"=>"6"}

【问题讨论】:

  • 你能告诉我们你到目前为止尝试了什么吗? (你写的一些代码,帮助你找到错误并建议你如何改进它)
  • sleeps.max_by{|x| x[:timeAsleep]} 这总是返回第一个值
  • 因为您正在访问x[:timeAsleep],但哈希中的键不是符号,而是字符串,所以x['timeAsleep'] 应该可以工作。
  • 欢迎来到 Stack Overflow。当提供像你的“哈希数组”这样的数据时,它需要在语法上是正确的。您提供的不是哈希数组。将其粘贴到 IRB 中,您会看到。我们还希望您向我们提供您为解决问题而编写的代码示例。 Stack Overflow 不是一个“为我编写代码”的网站,它是一个“我需要帮助调试我编写的代码的问题”的网站。请阅读“How to Ask”。事实上,我们不知道您尝试了什么,并且会编写与您编写的任何内容完全无关的代码。
  • 当你想要一个键的值的统计信息时,真的有必要有一个哈希有 18 个键的例子吗?比如说有两个键的例子怎么样?

标签: arrays ruby hash


【解决方案1】:

你可以这样做:

array.max_by {|x| x['timeAsleep']} # max
array.min_by {|x| x['timeAsleep']} # min
array.map {|x| x['timeAsleep']}.reduce(:+) / array.size.to_f # average

您可以在文档中阅读有关 mapreduce 的信息

【讨论】:

  • Map 在最后一个表达式中是多余的:array.reduce(0) {|m,x| m + x['timeAsleep']} / array.size
  • 这也将通过整数除法对平均值进行四舍五入;如果你想要精确的(十进制)平均值,你可以做array.reduce(0) { |m,x| m + x['timeAsleep'] }.to_f / array.size
  • array.max_byarray.min_by 返回哈希值,而不是值。
【解决方案2】:

一种更有效的方法是对哈希数组进行一次排序,而不是查找最大值/最小值等。

array = array_hash.sort_by {|k| k["timeAsleep"] }

然后你可以从排序后的数组中检索相应的哈希

puts "Hash with Smallest timeAsleep", array[0]
puts "Hash with Largest timeAsleep", array[array.length-1]

if ((array.length % 2) == 0)
    puts "Hash with Average timeAsleep", array[(array.size/2)-1]
else
    puts "Hash with Average timeAsleep", array[(array.size/2)]
end

【讨论】:

    【解决方案3】:
    arr = [
      {"id"=>"1", "timeAsleep"=>478, "timeAwake"=>9},
      {"id"=>"2", "timeAsleep"=>471, "timeAwake"=>6},
      {"id"=>"3", "timeAsleep"=>434, "timeAwake"=>22},
      {"id"=>"4", "timeAsleep"=>370, "timeAwake"=>0},
      {"id"=>"5", "timeAsleep"=>485, "timeAwake"=>502},
      {"id"=>"6", "timeAsleep"=>499, "timeAwake"=>7}] 
    
    sleep_times = arr.map { |h| h["timeAsleep"] }
      #=> [478, 471, 434, 370, 485, 499]
    

    timeAsleep的最小值和最大值

    sleep_times.minmax
      #=> [370, 499] 
    

    timeAsleep 的平均值

    sleep_times.reduce(:+).fdiv(arr.size).round(1)
      #=> 456.2
    

    最大值所有具有数值的键

    (我不确定你是否想要这个。)

    arr.map { |h| h.values.select { |v| v.kind_of?(Numeric) }.max }.max
      #=> 502
    

    【讨论】:

      猜你喜欢
      • 2014-06-11
      • 2013-12-23
      • 2015-01-16
      • 2016-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多