【问题标题】:Functional way to flatten nested array inside an object using lodash?使用 lodash 展平对象内的嵌套数组的功能性方法?
【发布时间】:2021-12-11 17:28:11
【问题描述】:

我有这个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'
}

【问题讨论】:

    标签: javascript functional-programming lodash


    【解决方案1】:

    感谢@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();
    

    【讨论】:

      【解决方案2】:

      您可以使用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",
      }; }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-10-19
        • 2021-11-29
        • 2022-01-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-04
        相关资源
        最近更新 更多