लापता मूल्यों के साथ हैश की एक सरणी भरें

Nov 25 2020

मैं ApexChart के लिए कुछ हीटमैप विनिर्देश चार्ट बनाने की कोशिश कर रहा हूं । अब तक, मुझे हश का यह एरे मिला, 3 गतिविधियों के लिए।

[{
  :name => "Activity 1",
  :data => {
    "May 2020" => 37, "June 2020" => 17, "July 2020" => 9, "August 2020" => 18
  }
}, {
  :name => "Activity 2",
  :data => {
    "May 2020" => 3
  }
}, {
  :name => "Activity 3",
  :data => {
    "July 2020" => 5, "November 2020" => 11
  }
}]

गतिविधि 3 पर, हमें केवल 2 महीने मिले जो हैं, Julyऔर November

मेरी आवश्यकता प्रत्येक हैश के लिए, सभी लापता तारीखों को भरने के लिए होगी, और उन्हें मान के रूप में 0 से भरना होगा। मेरे प्रतीक्षित परिणाम होंगे

[{
  :name => "Activity 1",
  :data => {
    "May 2020" => 37, "June 2020" => 17, "July 2020" => 9, "August 2020" => 18, "November 2020" => 0
  }
}, {
  :name => "Activity 2",
  :data => {
    "May 2020" => 3, "June 2020" => 0, "July 2020" => 0, "August 2020" => 0, "November 2020" => 0
  }
}, {
  :name => "Activity 3",
  :data => {
    "May 2020" => , "June 2020" => 0, "July 2020" => 5, "August 2020" => 0, "November 2020" => 11
  }
}]

हां, Septemberउद्देश्य से गायब है। मुझे लगता है कि इसे प्राप्त करने का सबसे अच्छा तरीका हर महीने, एक-एक करके प्राप्त करना होगा; फिर लापता महीनों के साथ प्रत्येक सरणियों को भरने के लिए; लेकिन मुझे नहीं पता कि इसे कैसे हासिल किया जाए।

जवाब

1 CarySwoveland Nov 26 2020 at 02:57

यदि arrआपके पास हैश की सरणी है, तो आप दो चरणों में वांछित सरणी का निर्माण कर सकते हैं।

require 'date'
date_fmt = "%B %Y"
first_month, last_month = arr.flat_map do |g|
  g[:data].keys
end.map { |s| Date.strptime(s, date_fmt) }.minmax
  #=> [#<Date: 2020-05-01 ((2458971j,0s,0n),+0s,2299161j)>,
  #    #<Date: 2020-11-01 ((2459155j,0s,0n),+0s,2299161j)>] 

h = (first_month..last_month).map do |d|
  d.strftime(date_fmt)
end.product([0]).to_h
  #=> {"May 2020"=>0, "June 2020"=>0, "July 2020"=>0, "August 2020"=>0,
  #    "September 2020"=>0, "October 2020"=>0, "November 2020"=>0} 
arr.map { |g| g.merge(:data => h.merge(g[:data])) }
  #=> [
  #     {
  #       :name=>"Activity 1",
  #       :data=>{
  #         "May 2020"=>37, "June 2020"=>17, "July 2020"=>9,
  #         "August 2020"=>18, "September 2020"=>0,
  #         "October 2020"=>0, "November 2020"=>0
  #       }
  #     },
  #     {
  #       :name=>"Activity 2",
  #       :data=>{
  #         "May 2020"=>3, "June 2020"=>0, "July 2020"=>0,
  #         "August 2020"=>0, "September 2020"=>0,
  #         "October 2020"=>0, "November 2020"=>0
  #       }
  #     },
  #     {
  #       :name=>"Activity 3",
  #       :data=>{
  #         "May 2020"=>0, "June 2020"=>0, "July 2020"=>5,
  #         "August 2020"=>0, "September 2020"=>0,
  #         "October 2020"=>0, "November 2020"=>11
  #       }
  #     }
  #   ] 

देखें Enumerable # flat_map , दिनांक :: strptime , सरणी # minmax , दिनांक # strftime , सरणी # उत्पाद और हैश # मर्ज । दिनांक स्वरूपण निर्देशों के लिए दिनांक समय # तारीख भी देखें ।

ध्यान दें कि की गणना में first_monthऔर last_month,

[#<Date: 2020-05-01 ((2458971j,0s,0n),+0s,2299161j)>,
 #<Date: 2020-11-01 ((2459155j,0s,0n),+0s,2299161j)>].
  map { |d| d.strftime(date_fmt) }
  #=> ["May 2020", "November 2020"]
1 KARASZIIstván Nov 25 2020 at 18:27

आप पहले महीनों को प्राप्त करके और फिर अपने मामले में हैश आइटम को संशोधित करके कुछ इसी तरह प्राप्त कर सकते हैं:

months = data.flat_map { |d| d[:data].keys }.to_set
data.each do |d|
  months.each do |month|
    d[:data][month] = 0 unless d[:data].key?(month)
  end
end

आप जो भी कर सकते हैं वह एक नया बनाने के लिए है Arrayजहां Hashमूल्यों को एक डिफ़ॉल्ट मान के साथ आरंभ किया जाता है:

data_with_default = data.map do |d|
  {
    name: d[:name],
    data: Hash.new(0).update(d[:data])
  }
end
BenTrewern Nov 25 2020 at 18:48

निम्नलिखित प्रयास करें:

a = [{
  :name => "Activity 1",
  :data => {
    "May 2020" => 37, "June 2020" => 17, "July 2020" => 9, "August 2020" => 18
  }
}, {
  :name => "Activity 2",
  :data => {
    "May 2020" => 3
  }
}, {
  :name => "Activity 3",
  :data => {
    "July 2020" => 5, "November 2020" => 11
  }
}]

months = ['May 2020', 'June 2020', 'July 2020', 'August 2020', 'November 2020']

puts a.map { |h| { name: h[:name], data: Hash[months.map { |m| [m, h[:data][m] ? h[:data][m] : 0] }] } }