簡體   English   中英

使用lodash在對象內展平嵌套數組的功能方法?

[英]Functional way to flatten nested array inside an object using lodash?

我有這個facebookResponseObject ,我想展平數組類型的值

現在我正在使用這樣的 reduce 函數,但我想知道是否有更簡潔的功能方法來解決這個問題......

輸入樣本

const facebookResponseObject = {
  account_currency: "xxx",
  campaign_name: "xxxxxxxx",
  account_name: "xxxxxxxx",
  adset_name: "xxxxxxxx",
  ad_name: "xxxxxxxx",
  reach: "xxxx",
  impressions: "xxxx",
  frequency: "xxxx",
  spend: "xxxx",
  cpm: "xxxx",
  inline_link_clicks: "xxxx",
  cost_per_inline_link_click: "xxxx",
  inline_link_click_ctr: "xxxx",
  clicks: "xxxx",
  cost_per_unique_click: "xxxx",
  cost_per_action_type: [
    { action_type: "link_click", value: "xxxx" },
    { action_type: "landing_page_view", value: "xxxx" },
    { action_type: "post_engagement", value: "xxxx" },
    { action_type: "page_engagement", value: "xxxx" },
    { action_type: "lead", value: "xxxx" },
    { action_type: "video_view", value: "xxxx" },
    { action_type: "like", value: "xxxx" },
  ],
  actions: [
    { action_type: "link_click", value: "xxxx" },
    { action_type: "landing_page_view", value: "xxxx" },
    { action_type: "post_engagement", value: "xxxx" },
    { action_type: "page_engagement", value: "xxxx" },
    { action_type: "post_reaction", value: "xxxx" },
    { action_type: "lead", value: "xxxx" },
    { action_type: "post", value: "xxxx" },
    { action_type: "comment", value: "xxxx" },
    { action_type: "video_view", value: "xxxx" },
    { action_type: "like", value: "xxxx" },
  ],
  test_key: [
    { action_type: "test1", value: "xxxx" },
    { action_type: "test2", value: "xxxx" },
    { action_type: "test3", value: "xxxx" },
    { action_type: "test4", value: "xxxx" },
  ],
  cpc: "xxxx",
  ctr: "xxxx",
  date_start: "xxxx-xx-xx",
  date_stop: "xxxx-xx-xx",
  account_id: "xxxxxxxx",
};

變換函數

const formatResponse = _.reduce(
  facebookResponseObject,
  (acc, cur, key) => {
    if (_.isArray(cur)) {
      acc = {
        ...acc,
        ..._.chain(cur)
          .keyBy(obj => `${key}.${obj.action_type}`)
          .mapValues(v => v.value)
          .value(),
      };
    } else {
      acc[key] = cur;
    }
    return acc;
  },
  {},
);

輸出

{
  account_currency: 'xxx',
  campaign_name: 'xxxxxxxx',
  account_name: 'xxxxxxxx',
  adset_name: 'xxxxxxxx',
  ad_name: 'xxxxxxxx',
  reach: 'xxxx',
  impressions: 'xxxx',
  frequency: 'xxxx',
  spend: 'xxxx',
  cpm: 'xxxx',
  inline_link_clicks: 'xxxx',
  cost_per_inline_link_click: 'xxxx',
  inline_link_click_ctr: 'xxxx',
  clicks: 'xxxx',
  cost_per_unique_click: 'xxxx',
  'cost_per_action_type.link_click': 'xxxx',
  'cost_per_action_type.landing_page_view': 'xxxx',
  'cost_per_action_type.post_engagement': 'xxxx',
  'cost_per_action_type.page_engagement': 'xxxx',
  'cost_per_action_type.lead': 'xxxx',
  'cost_per_action_type.video_view': 'xxxx',
  'cost_per_action_type.like': 'xxxx',
  'actions.link_click': 'xxxx',
  'actions.landing_page_view': 'xxxx',
  'actions.post_engagement': 'xxxx',
  'actions.page_engagement': 'xxxx',
  'actions.post_reaction': 'xxxx',
  'actions.lead': 'xxxx',
  'actions.post': 'xxxx',
  'actions.comment': 'xxxx',
  'actions.video_view': 'xxxx',
  'actions.like': 'xxxx',
  'test_key.test1': 'xxxx',
  'test_key.test2': 'xxxx',
  'test_key.test3': 'xxxx',
  'test_key.test4': 'xxxx',
  cpc: 'xxxx',
  ctr: 'xxxx',
  date_start: 'xxxx-xx-xx',
  date_stop: 'xxxx-xx-xx',
  account_id: 'xxxxxxxx'
}

您可以使用flatMap來迭代對象的條目。

  • 不要觸摸具有非數組值的條目
  • 當有數組值時,迭代其元素以返回新的鍵值對
    • 作為鍵,將原始鍵與action_type
    • 作為一個值,取value屬性
  • 因為我們使用的是flatMap ,所以我們確保我們不會返回嵌套列表。
  • 使用Object.fromEntries轉換回對象

 const flatEntries = (obj) => Object .entries(obj) .flatMap( ([ k, v ]) => Array.isArray(v) ? v.map(a => [ `${k}.${a.action_type}`, a.value ] ) : [[k, v]] ); const flattenObject = obj => Object.fromEntries(flatEntries(obj)); console.log(flattenObject(facebookResponseObject())); function facebookResponseObject() { return { account_currency: "xxx", campaign_name: "xxxxxxxx", account_name: "xxxxxxxx", adset_name: "xxxxxxxx", ad_name: "xxxxxxxx", reach: "xxxx", impressions: "xxxx", frequency: "xxxx", spend: "xxxx", cpm: "xxxx", inline_link_clicks: "xxxx", cost_per_inline_link_click: "xxxx", inline_link_click_ctr: "xxxx", clicks: "xxxx", cost_per_unique_click: "xxxx", cost_per_action_type: [ { action_type: "link_click", value: "xxxx" }, { action_type: "landing_page_view", value: "xxxx" }, { action_type: "post_engagement", value: "xxxx" }, { action_type: "page_engagement", value: "xxxx" }, { action_type: "lead", value: "xxxx" }, { action_type: "video_view", value: "xxxx" }, { action_type: "like", value: "xxxx" }, ], actions: [ { action_type: "link_click", value: "xxxx" }, { action_type: "landing_page_view", value: "xxxx" }, { action_type: "post_engagement", value: "xxxx" }, { action_type: "page_engagement", value: "xxxx" }, { action_type: "post_reaction", value: "xxxx" }, { action_type: "lead", value: "xxxx" }, { action_type: "post", value: "xxxx" }, { action_type: "comment", value: "xxxx" }, { action_type: "video_view", value: "xxxx" }, { action_type: "like", value: "xxxx" }, ], test_key: [ { action_type: "test1", value: "xxxx" }, { action_type: "test2", value: "xxxx" }, { action_type: "test3", value: "xxxx" }, { action_type: "test4", value: "xxxx" }, ], cpc: "xxxx", ctr: "xxxx", date_start: "xxxx-xx-xx", date_stop: "xxxx-xx-xx", account_id: "xxxxxxxx", }; }

感謝@user3297291的幫助,我將使用稍微修改過的版本來回答您的問題(使用 lodash)

const formatResponse = obj =>
  _.chain(obj)
    .toPairs()
    .flatMap(([key, value]) =>
      _.isArray(value)
        ? _.map(value, actionObj => [`${key}.${actionObj.action_type}`, actionObj.value])
        : [[key, value]],
    )
    .fromPairs()
    .value();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM