将JS子对象合并到具有连接键的JS对象中

时间:2017-03-12 19:26:34

标签: javascript json node.js

我正在编写用于将node.js模块发布到GitHub和NPM的模板软件。一个示例模板的小片段:

  

{{module.name}}

     

{{module.description}}

     

目的

     

{{module.code.purpose}}

我有一个带有所有这些属性的对象,例如

{
  "module" : {
    "name" : "test",
    "description" : "Test module"
...

问题是我需要合并这个对象的子对象,所以最终输出看起来像这样(用于替换模板中的占位符):

{
  "module.name" : "test",
  "module.description" : "Test module"
...

所以我创建了自己的功能:

/**
    Takes an object like
    {
        "type" : "meal",
        "pizza" : {
            "toppings" : ["pepperoni", "cheese"],
            "radius" : 6,
            "metadata" : {
                "id" : 24553
            }
        }
    }
    and changes it to
    {
        "type" : "meal",
        "pizza.toppings" : ["pepperoni", "cheese"],
        "pizza.radius" : 6,
        "pizza.metadata.id" : 244553
    }
*/
const mergeObjectsToKeys = object => {

    // Loop through the passed in object's properties

    return Object.entries(object).reduce((obj, [key, value]) => {

        // Check if it is a sub-object or not

        if (typeof value === "object") {

            // If it is a sub-object, merge its properties with recursion and then put those keys into the master object

            const subObject = mergeObjectsToKeys(value);

            Object.entries(subObject).forEach(([key2, value2]) => {
                obj[key + "." + key2] = value2;
            });
        } else {

            // Otherwise, just put the key into the object to return

            obj[key] = value;
        }
    }, { });
};

两个问题

  • 这是编写软件的正确方法吗?
  • 如果有,是否有内置功能来合并子对象,如上所示?

1 个答案:

答案 0 :(得分:2)

处理要求的一个内置函数是Object.assign();你可以使用spread元素Object.entries().map()来设置对象属性的属性名称。

处理value不是嵌套对象的对象

let p = Object.keys(o).pop();
let res = Object.assign({}, ...Object.entries(o.module).map(([key, prop]) =>
            ({[`${p}.${key}`]: prop})));

处理嵌套对象的值

let o = {
  "type": "meal",
  "pizza": {
    "toppings": ["pepperoni", "cheese"],
    "radius": 6,
    "metadata": {
      "id": 24553
    }
  }
}

let res = Object.assign({}, ...Object.entries(o).map(([prop, value]) => 
            typeof value === "object" && !Array.isArray(value) 
            ? Object.assign({}, ...Object.entries(value)
              .map(([key,val]) => ({[`${prop}.${key}`]: key})))
            : {[prop]: value})
          );

console.log(res);