【问题标题】:Modify structure of deeply nested object into an array of objects将深度嵌套对象的结构修改为对象数组
【发布时间】:2020-12-18 03:28:13
【问题描述】:

我有一个深度嵌套的 javascript 对象,它可以包含一个属性字段 - 这是一个对象,其中键表示属性名称,值表示其余属性数据。我想将属性对象转换为键与值组合的对象数组。 例如,这就是我所拥有的:

const test = {
    properties: {
      meta: {
        type: 'object',
        properties: {
          agencyId: {
            type: 'string',
            example: 'e767c439-08bf-48fa-a03c-ac4a09eeee8f',
            description: 'agencyId',
          },
        },
      },
      data: {
        type: 'object',
        properties: {
          intervalStartTime: {
            type: 'string',
            description: 'Time in GMT',
            example: '1591702200000',
          },
          group: {
            type: 'object',
            properties: {
              groupType: {
                type: 'string',
                description: 'Group Type',
                example: 'vip',
              },
              numberofRequests: {
                type: 'number',
                example: 10198,
                description: 'Amount of requests coming from group',
              },
            },
          },
        },
      },
    },
  }

这就是我想要的:

const test = {
  properties: [
    {
      name: 'meta',
      type: 'object',
      properties: [
        [
          {
            type: 'string',
            example: 'e767c439-08bf-48fa-a03c-ac4a09eeee8f',
            description: 'agencyId',
            name: 'agencyId',
          },
        ],
      ],
    },
    {
      name: 'data',
      type: 'object',
      properties: [
        [
          {
            type: 'string',
            description: 'Time in GMT',
            example: '1591702200000',
            name: 'intervalStartTime',
          },
          {
            name: 'group',
            type: 'object',
            properties: [
              {
                name: 'groupType',
                type: 'string',
                description: 'Group Type',
                example: 'vip',
              },
              {
                name: 'numberOfRequests',
                type: 'number',
                example: 10198,
                description: 'Amount of requests coming from group',
              },
            ],
          },
        ],
      ],
    },
  ],
}

我有一个帮助函数,可以将对象转换为我想要的形式,但我正在努力递归地修改嵌套属性。这就是我所拥有的。关于如何将整个对象修改为我需要的结构的任何建议?

 const convertObj = (obj) => {
    return Object.entries(obj).reduce((initialVal, [name, nestedProperty]) => {
      initialVal.push({ ...nestedProperty, name })
      return initialVal
    }, [])
  }

 const getNestedProperties = (data) => {
    for (const key in data) {
      const keyDetails = data[key]
      if (keyDetails.hasOwnProperty('properties')) {
        const keyProperties = keyDetails['properties']
        keyDetails['properties'] = []
        keyDetails['properties'].push(convertObj(keyProperties))
        getNestedProperties(keyProperties)
      }
    }
  }

【问题讨论】:

    标签: javascript arrays object recursion


    【解决方案1】:

    如果对象具有properties 键,则映射条目并创建一个对象数组,每个键为name,其余为值。遍历对象并检查每个属性是否是对象。如果是,递归调用该函数。 { ...o } 部分会创建输入的副本,因此不会发生变异。

    const test = {properties:{meta:{type:"object",properties:{agencyId:{type:"string",example:"e767c439-08bf-48fa-a03c-ac4a09eeee8f",description:"agencyId",},},},data:{type:"object",properties:{intervalStartTime:{type:"string",description:"Time in GMT",example:"1591702200000",},group:{type:"object",properties:{groupType:{type:"string",description:"Group Type",example:"vip",},numberofRequests:{type:"number",example:10198,description:"Amount of requests coming from group",}}}}}}};
    
    function convert({ ...o }) {
      for (const key in o) {
        if (typeof o[key] === 'object')
          o[key] = convert(o[key])
      }
    
      if (o.hasOwnProperty("properties"))
        o.properties = Object.entries(o.properties).map(([name, v]) => ({ name, ...v }))
    
      return o
    }
    
    console.log(convert(test))

    【讨论】:

      【解决方案2】:

      如果您没有properties 属性,则只需返回对象的其余部分。如果这样做,则返回对象的其余部分加上 properties 数组属性,该属性通过获取该属性中的每个名称-值条目并通过将属性 name 添加到调用 transform 的结果将其转换为对象那个value

      代码相当简单:

      const transform = ({properties, ...rest} = {}) =>
        properties 
          ? {
              ... rest, 
              properties: Object .entries (properties) .map (([name, val]) => ({
                name, 
                ... transform (val)
              }))
            }
          : {... rest}
      
      const test = {properties: {meta: {type: 'object', properties: {agencyId: {type: 'string', example: 'e767c439-08bf-48fa-a03c-ac4a09eeee8f', description: 'agencyId'}}}, data: {type: 'object', properties: {intervalStartTime: {type: 'string', description: 'Time in GMT', example: '1591702200000'}, oup: {type: 'object', properties: {grupType: {type: 'string', description: 'Group Type', example: 'vip'}, numberofRequests: { type: 'number', example: 10198, description: 'Amount of requests coming from group'}}}}}}}
      
      console .log (transform (test))
      .as-console-wrapper {max-height: 100% !important; top: 0}

      【讨论】:

        【解决方案3】:

        这是object-scan 完成繁重工作的解决方案。请注意,这是有效的,因为遍历发生在删除安全顺序中。

        // const objectScan = require('object-scan');
        
        const test = { properties: { meta: { type: 'object', properties: { agencyId: { type: 'string', example: 'e767c439-08bf-48fa-a03c-ac4a09eeee8f', description: 'agencyId' } } }, data: { type: 'object', properties: { intervalStartTime: { type: 'string', description: 'Time in GMT', example: '1591702200000' }, group: { type: 'object', properties: { groupType: { type: 'string', description: 'Group Type', example: 'vip' }, numberofRequests: { type: 'number', example: 10198, description: 'Amount of requests coming from group' } } } } } } };
        
        const rewrite = (obj) => objectScan(['**.properties'], {
          rtn: 'count', // returns number of rewrites
          filterFn: ({ value, parent, property }) => {
            parent[property] = Object.entries(value)
              .map(([name, v]) => ({ name, ...v }));
          }
        })(obj);
        
        console.log(rewrite(test));
        // => 4
        console.log(test);
        // => { properties: [ { name: 'meta', type: 'object', properties: [ { name: 'agencyId', type: 'string', example: 'e767c439-08bf-48fa-a03c-ac4a09eeee8f', description: 'agencyId' } ] }, { name: 'data', type: 'object', properties: [ { name: 'intervalStartTime', type: 'string', description: 'Time in GMT', example: '1591702200000' }, { name: 'group', type: 'object', properties: [ { name: 'groupType', type: 'string', description: 'Group Type', example: 'vip' }, { name: 'numberofRequests', type: 'number', example: 10198, description: 'Amount of requests coming from group' } ] } ] } ] }
        .as-console-wrapper {max-height: 100% !important; top: 0}
        <script src="https://bundle.run/object-scan@13.7.1"></script>

        免责声明:我是object-scan的作者

        【讨论】:

          猜你喜欢
          • 2019-03-15
          • 1970-01-01
          • 2021-07-14
          • 1970-01-01
          • 2018-04-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-01-13
          相关资源
          最近更新 更多