Techioz Blog

map doを使用してネストされた配列を持つオブジェクトの配列をリファクタリングする

概要

次のコードを使用して、複数のオブジェクトの配列内に存在する「usageByMonth」配列を再マップしようとしています。

categorisedFeatures = response[:categorisedFeatures].map do |feature|
   newHistorical = (feature.dig(1, :historical)).map do |historical|
     usageByMonthRefactor = historical.dig(:usageByMonth)&.map { |(k, v)| { 'month': k, 'value': v } }
           newEntry = historical.merge({
               usageByMonth: usageByMonthRefactor
            })
     end
    newFeature = feature.dig(1).merge ({
      historical: newHistorical
    }) 
 feature&.map { |(k,v)| k=k , v=newFeature}

 end

問題は、出力が同じ「履歴」オブジェクトを複数回繰り返していることですが、その理由がわかりません。

以下は、「feature」要素の 1 つの出力例です。

CMS {:historyal=>[{:internalName=>“TOTAL_BLOG_POSTS_LIVE_EOM”, :definition=>“ブログライブ”, :toolTip=>“レポート月末のステータスが「公開済み」のブログの数。”, :tags =>[]、:type=>“NUMBER”、:name=>“ブログ”、:usageByMonth=>[{:month=>:SEP、:value=>“741”}、{:month=>:OCT , :value=>“741”}, {:month=>:AUG, :value=>“741”}]}, {:internalName=>“BLOG_POST_VIEWS”, :setting=>“ページビュー”, :toolTip= >:null, :tags=>[], :type=>“NUMBER”, :name=>“ブログ”, :usageByMonth=>[{:month=>:SEP, :value=>“6651”}, { :month=>:OCT, :value=>“6601”}, {:month=>:AUG, :value=>“6957”}]}, {:internalName=>“LANDING_PAGE_VIEWS”, :setting=>“ページビュー”、:toolTip=>:null、:tags=>[]、:type=>“NUMBER”、:name=>“ランディング ページ”、:usageByMonth=>[{:month=>:SEP、:value= >“68”}、{:month=>:OCT、:value=>“163”}、{:month=>:AUG、:value=>“116”}]}、{:internalName=>“WEBSITE_PAGE_VIEWS” , :setting=>“ページビュー”, :toolTip=>:null, :tags=>[], :type=>“NUMBER”, :name=>“ウェブサイトページ”, :usageByMonth=>[{:month= >:SEP, :value=>“1041”}, {:month=>:OCT, :value=>“979”}, {:month=>:AUG, :value=>“1268”}]}], :リアルタイム=>[]} {:historyal=>[{:internalName=>“TOTAL_BLOG_POSTS_LIVE_EOM”, :definition=>“ブログライブ”, :toolTip=>“レポート月末のステータスが「公開済み」のブログの数。”, :tags =>[]、:type=>“NUMBER”、:name=>“ブログ”、:usageByMonth=>{:SEP=>“741”、:OCT=>“741”、:AUG=>“741”} }, {:internalName=>“BLOG_POST_VIEWS”, :setting=>“ページビュー”, :toolTip=>:null, :tags=>[], :type=>“NUMBER”, :name=>“ブログ”, :usageByMonth=>{:SEP=>“6651”, :OCT=>“6601”, :AUG=>“6957”}}, {:internalName=>“LANDING_PAGE_VIEWS”, :setting=>“ページビュー”, : toolTip=>:null、:tags=>[]、:type=>“NUMBER”、:name=>“ランディング ページ”、:usageByMonth=>{:SEP=>“68”、:OCT=>“163” , :AUG=>“116”}}, {:internalName=>“WEBSITE_PAGE_VIEWS”, :definition=>“ページビュー”, :toolTip=>:null, :tags=>[], :type=>“NUMBER” 、:name=>“Web サイト ページ”、:usageByMonth=>{:SEP=>“1041”、:OCT=>“979”、:AUG=>“1268”}}]、:realtime=>[]} {:historyal=>[{:internalName=>“TOTAL_BLOG_POSTS_LIVE_EOM”, :definition=>“ブログライブ”, :toolTip=>“レポート月末のステータスが「公開済み」のブログの数。”, :tags =>[]、:type=>“NUMBER”、:name=>“ブログ”、:usageByMonth=>[{:month=>:SEP、:value=>“741”}、{:month=>:OCT , :value=>“741”}, {:month=>:AUG, :value=>“741”}]}, {:internalName=>“BLOG_POST_VIEWS”, :setting=>“ページビュー”, :toolTip= >:null, :tags=>[], :type=>“NUMBER”, :name=>“ブログ”, :usageByMonth=>[{:month=>:SEP, :value=>“6651”}, { :month=>:OCT, :value=>“6601”}, {:month=>:AUG, :value=>“6957”}]}, {:internalName=>“LANDING_PAGE_VIEWS”, :setting=>“ページビュー”、:toolTip=>:null、:tags=>[]、:type=>“NUMBER”、:name=>“ランディング ページ”、:usageByMonth=>[{:month=>:SEP、:value= >“68”}、{:month=>:OCT、:value=>“163”}、{:month=>:AUG、:value=>“116”}]}、{:internalName=>“WEBSITE_PAGE_VIEWS” , :setting=>“ページビュー”, :toolTip=>:null, :tags=>[], :type=>“NUMBER”, :name=>“ウェブサイトページ”, :usageByMonth=>[{:month= >:SEP, :value=>“1041”}, {:month=>:OCT, :value=>“979”}, {:month=>:AUG, :value=>“1268”}]}], :リアルタイム=>[]}

私の元の入力は次のとおりです。

response = {
  "months": [
    "AUG",
    "SEP",
    "OCT"
  ],
  "categorisedTiers": {
    "CMS": "FREE",
    "MARKETING": "FREE",
    "OPERATIONS": "FREE",
    "SALES": "FREE",
    "SERVICE": "FREE"
  },
  "categorisedFeatures": {
    "PLATFORM": {
      "historical": [
        {
          "internalName": "TOTAL_CONTACTS_CREATED_IN_MONTH",
          "definition": "New contacts",
          "toolTip": "Number of contacts that were created in the report month.",
          "tags": [],
          "type": "NUMBER",
          "name": "Contacts",
          "usageByMonth": {
            "SEP": "33",
            "OCT": "35",
            "AUG": "40"
          }
        },
        {
          "internalName": "TOTAL_CONTACTS_QUALIFIED_IN_MONTH",
          "definition": "MQLs",
          "toolTip": "Number of contacts that were set with internal value 'marketingqualifiedlead' in the 'lifecycle stage' property in the report month.",
          "tags": [],
          "type": "NUMBER",
          "name": "Contacts",
          "usageByMonth": {
            "SEP": "0",
            "OCT": "0",
            "AUG": "0"
          }
        },
        {
          "internalName": "TOTAL_CONTACTS_BECAME_CUSTOMERS_IN_MONTH",
          "definition": "Customers",
          "toolTip": "Number of contacts that were set with internal value 'customer' in the 'lifecycle stage' property in the report month.",
          "tags": [],
          "type": "NUMBER",
          "name": "Contacts",
          "usageByMonth": {
            "SEP": "0",
            "OCT": "0",
            "AUG": "0"
          }
        },
        {
          "internalName": "CONTACTS_SCORED",
          "definition": "Contacts scored",
          "toolTip": "Overall percentage of all contacts with the 'HubSpot score' not equal to 0, in the report month.",
          "tags": [
            "PRO+"
          ],
          "type": "PERCENTAGE",
          "name": "Contacts",
          "usageByMonth": {
            "SEP": "25.09",
            "OCT": "25.05",
            "AUG": "25.11"
          }
        },
        {
          "internalName": "PERCENTAGE_CONTACTS_ASSIGNED",
          "definition": "Contacts assigned",
          "toolTip": "Overall percentage of contacts with an owner.",
          "tags": [],
          "type": "PERCENTAGE",
          "name": "Contacts",
          "usageByMonth": {
            "SEP": "19.67",
            "OCT": "19.65",
            "AUG": "19.67"
          }
        },
        {
          "internalName": "TOTAL_CONTACTS_CONTACTED_IN_MONTH",
          "definition": "Contacts contacted",
          "toolTip": "Number of contacts that were contacted through a call, chat conversation, LinkedIn message, postal mail, meeting, sales email, SMS, or WhatsApp message in the report month.",
          "tags": [],
          "type": "NUMBER",
          "name": "Contacts",
          "usageByMonth": {
            "SEP": "3",
            "OCT": "3",
            "AUG": "5"
          }
        },
        {
          "internalName": "TOTAL_CONVERSATIONS_STARTED_IN_MONTH",
          "definition": "Conversations started",
          "toolTip": "Number of conversations started, via any channel, in the report month (e.g. emails, chats, FaceBook Messanger, etc.)",
          "tags": [],
          "type": "NUMBER",
          "name": "Conversations",
          "usageByMonth": {
            "SEP": "0",
            "OCT": "0",
            "AUG": "0"
          }
        },
        {
          "internalName": "TOTAL_CUSTOM_REPORTS",
          "definition": "Custom reports",
          "toolTip": "Total number of custom reports as of the end of the report month.",
          "tags": [],
          "type": "NUMBER",
          "name": "Reporting",
          "usageByMonth": {
            "AUG": "27",
            "SEP": "27",
            "OCT": "27"
          }
        },
        {
          "internalName": "TOTAL_DASHBOARDS",
          "definition": "Dashboards",
          "toolTip": "Total number of dashboards as of the end of the report month.",
          "tags": [],
          "type": "NUMBER",
          "name": "Reporting",
          "usageByMonth": {
            "AUG": "4",
            "SEP": "4",
            "OCT": "4"
          }
        },
        {
          "internalName": "TOTAL_TEMPLATE_EMAIL_SENDS_THIS_MONTH",
          "definition": "Templates sent",
          "toolTip": :null,
          "tags": [],
          "type": "NUMBER",
          "name": "Templates",
          "usageByMonth": {
            "SEP": "0",
            "OCT": "0",
            "AUG": "0"
          }
        },
        {
          "internalName": "TOTAL_PAGE_VIEWS",
          "definition": "Page views",
          "toolTip": "Number of page views recorded in the report month. A page view is counted every time the HubSpot tracking code is loaded on a browser.",
          "tags": [],
          "type": "NUMBER",
          "name": "Traffic Analytics",
          "usageByMonth": {
            "SEP": "13522",
            "OCT": "12599",
            "AUG": "18599"
          }
        },
        {
          "internalName": "TOTAL_WORKFLOWS_CREATED_IN_MONTH",
          "definition": "Workflows created",
          "toolTip": :null,
          "tags": [
            "PRO+"
          ],
          "type": "NUMBER",
          "name": "Workflows",
          "usageByMonth": {
            "SEP": "0",
            "OCT": "1",
            "AUG": "0"
          }
        }
      ],
      "realtime": [
        {
          "internalName": "TOTAL_CUSTOM_OBJECTS",
          "definition": "Active custom objects",
          "toolTip": "Total number of active custom objects. This data is real time.",
          "tags": [
            "ENTERPRISE"
          ],
          "type": "NUMBER",
          "name": "Custom Objects",
          "realtimeValue": "0"
        }
      ]
    },
    "OPERATIONS": {
      "historical": [
        {
          "internalName": "DUPLICATE_RECORDS",
          "definition": "Duplicate records",
          "toolTip": "Count of duplicate records at end of report month.",
          "tags": [
            "PRO+"
          ],
          "type": "NUMBER",
          "name": "Data Quality",
          "usageByMonth": {
            "AUG": "0",
            "SEP": "0",
            "OCT": "0"
          }
        },
        {
          "internalName": "TOTAL_PROGRAMMABLE_ACTION_EVENTS",
          "definition": "Programmable actions",
          "toolTip": :null,
          "tags": [
            "PRO+"
          ],
          "type": "NUMBER",
          "name": "Workflows",
          "usageByMonth": {
            "SEP": "0",
            "OCT": "0",
            "AUG": "0"
          }
        }
      ],
      "realtime": [
        {
          "internalName": "DATASETS_CREATED",
          "definition": "Datasets live",
          "toolTip": "Number of datasets at the end of the report month. This data is real time.",
          "tags": [
            "ENTERPRISE"
          ],
          "type": "NUMBER",
          "name": "Dataset",
          "realtimeValue": "0"
        }
      ]
    },
    "CMS": {
      "historical": [
        {
          "internalName": "TOTAL_BLOG_POSTS_LIVE_EOM",
          "definition": "Blogs live",
          "toolTip": "Number of blogs with a \"published\" status at the end of the report month.",
          "tags": [],
          "type": "NUMBER",
          "name": "Blogs",
          "usageByMonth": {
            "SEP": "741",
            "OCT": "741",
            "AUG": "741"
          }
        },
        {
          "internalName": "BLOG_POST_VIEWS",
          "definition": "Page views",
          "toolTip": :null,
          "tags": [],
          "type": "NUMBER",
          "name": "Blogs",
          "usageByMonth": {
            "SEP": "6651",
            "OCT": "6601",
            "AUG": "6957"
          }
        },
        {
          "internalName": "LANDING_PAGE_VIEWS",
          "definition": "Page views",
          "toolTip": :null,
          "tags": [],
          "type": "NUMBER",
          "name": "Landing Pages",
          "usageByMonth": {
            "SEP": "68",
            "OCT": "163",
            "AUG": "116"
          }
        },
        {
          "internalName": "WEBSITE_PAGE_VIEWS",
          "definition": "Page views",
          "toolTip": :null,
          "tags": [],
          "type": "NUMBER",
          "name": "Website Pages",
          "usageByMonth": {
            "SEP": "1041",
            "OCT": "979",
            "AUG": "1268"
          }
        }
      ],
      "realtime": []
    }
    
  }
}

助けていただければ幸いです。

最後の「map」引数の代わりに、最後に「newFeature」を再宣言してみました。ただし、繰り返される「履歴」オブジェクトがなくなったときにこれが発生すると、「キー」値が取得できません。たとえば、最初のオブジェクトのキーは「PLATFORM」です。

解決策

コードの次の行が重複の原因です。

feature&.map { |(k,v)| k=k , v=newFeature}

feature には 2 つの要素があるため、簡単な例を示します。

[0,1]&.map { |(k,v)| k=2 , v=3} =>>>> [[2, 3], [2, 3]]

この場合、feature を配列に入れて最後に flatten を追加すると問題は解決します。

[feature]&.map { |(k,v)| k=k , v=newFeature}.flatten