首页 > 解决方案 > 如何在对象中保留一些深层道具?

问题描述

如何在对象中保留一些深层道具?

以下是一个示例对象。

    const sample_object = {
      prop1: {
        subprop1: {
          anothersubprop1: {
            properties: {realprop: {properties: {type: 'real_value', unwantedProps1: {}, unwantedProps2: {}}}
            $ref: {},
          },
          unwantedAnotherSubProp1: {},
          ...
        },
        unwantedSubProp1: {},
        ...
      },
      unwantedProp1: {},
      prop2: {
        subprop1: {
          anothersubprop1: {
            properties: {realprop: {type: 'real_value'}},
            $ref: {},
          },
          unwantedAnotherSubProp1: {},
          ...
        },
        unwantedSubProp1: {},
        unwantedSubProp2: {},
        subprop2: {
          anothersubprop1: {
            properties: {realprop: {type: 'real_value'}},
            $ref: {},
          },
          anothersubprop2: {
            properties: {
              properties: {realprop: {type: 'real_value'}},
              $ref: {},
            },
            unwantedAnotherSubProp1: {},
            unwantedAnotherSubProp2: {},
            $ref: {},
          },
          ...
        },
        unwantedSubProp3: {},
        unwantedSubProp4: {},
        ...
      },
      unwantedProp2: {},
      prop3: {
        subprop1: {
          anothersubprop1: {
            properties: {realprop: {type: 'real_value'}},
            $ref: {},
          },
        },
        subprop2: {
          anothersubprop1: {
            properties: {},
            $ref: {},
          },
          unwantedAnotherSubProp1: {},
        },
        unwantedSubProp1: {},
        unwantedSubProp2: {},
        ...
      },
      unwantedProp3: {},
...
      properties: {realprop: {type: 'real_value'}},
      $ref: {},
    };

如何仅保留以下道具,同时深入删除所有其他道具?

            properties: {realprop: {type: 'real_value'}},
            $ref: {},


// 注意上面两个不需要的 props 子的所有 props 也将被删除。

另请注意,在上述两个必需的道具中,我们需要替换

properties: {realprop: {type: 'real_value'}}

进入 :

properties: {realprop: 'real_value', name: 'Real Value', size: 10}

所以最终需要的道具将有:

properties: {realprop: 'real_value', name: 'Real Value', size: 10},
$ref: {},

我们在这里添加了一个名为 name 的额外属性(这将是值 'real_value' 的句子形式(来自 realprop:'real_value')和大小(这将是所有常量)。

以下是预期结果:

 const expected_object = {
      prop1: {
        subprop1: {
          anothersubprop1: {
            properties: {realprop: 'real_value', name: 'Real Value'},
            $ref: {},
          },
          ...
        },
        ...
      },
      prop2: {
        subprop1: {
          anothersubprop1: {
            properties: {realprop: 'real_value', name: 'Real Value', size: 10},
            $ref: {},
          },
          ...
        },
        subprop2: {
          anothersubprop1: {
            properties: {realprop: 'real_value', name: 'Real Value', size: 10},
            $ref: {},
          },
          anothersubprop2: {
            properties: {
              properties: {realprop: 'real_value', name: 'Real Value', size: 10},
              $ref: {},
            },
            $ref: {},
          },
          ...
        },
        ...
      },
      prop3: {
        subprop1: {
          anothersubprop1: {
            properties: {realprop: 'real_value', name: 'Real Value', size: 10},
            $ref: {},
          },
        },
        subprop2: {
          anothersubprop1: {
            properties: {realprop: 'real_value', name: 'Real Value', size: 10},
            $ref: {},
          },
        },
        ...
      },
...
      properties: {realprop: 'real_value', name: 'Real Value', size: 10},
      $ref: {},
    };

如果 lodash 或任何其他类似的库是可能的,请建议 或任何自定义代码

更新:我做了一个小更新。请也考虑一下

标签: javascript

解决方案


解决这个问题的递归方法是迭代每一层,直到你得到一个没有孩子的属性。

const treeTrim = (obj) => {
    let result = {}
    Object.keys(obj).forEach(e => {
        if (saveList.has(e)) {
            result[e] = obj[e]
        }

        else if (typeof (obj[e] == "object") && Object.keys(obj[e]).length > 0) {
            result[e] = treeTrim(obj[e])
        }
    })
    return result
}

const capitalize = (s) => {
    if (typeof s !== 'string') return ''
    return s.charAt(0).toUpperCase() + s.slice(1)
}

const formatProperties = (obj) => {
    let result = {}
    Object.keys(obj).forEach(e => {

        if (e === "properties" && Object.keys(obj[e]).length > 0) {
            if (obj[e].realprop && obj[e].realprop.type) {
                const value = obj[e].realprop.type
                let capitalizeValue = value.replace("_", " ").split(" ")
                capitalizeValue = capitalizeValue.map(e =>  { return capitalize(e) }).join(" ")
                result[e] = { realprop: value, name: capitalizeValue, size: capitalizeValue.length }
            }
            else {
                result[e] = obj[e]
            }
        }
        else if (typeof (obj[e] == "object") && Object.keys(obj[e]).length > 0) {
            result[e] = formatProperties(obj[e])
        }
    })
    return result
}

运行示例:

const sample_object = {
    prop1: {
        subprop1: {
            anothersubprop1: {
                properties: { realprop: { type: 'real_value' } },
                $ref: {},
            },
            unwantedAnotherSubProp1: {},
        },
        unwantedSubProp1: {},
    },
    unwantedProp1: {},
    prop2: {
        subprop1: {
            anothersubprop1: {
                properties: { realprop: { type: 'real_value' } },
                $ref: {},
            },
            unwantedAnotherSubProp1: {},
        },
        unwantedSubProp1: {},
        unwantedSubProp2: {},
        subprop2: {
            anothersubprop1: {
                properties: { realprop: { type: 'real_value' } },
                $ref: {},
            },
            anothersubprop2: {
                properties: {
                    properties: { realprop: { type: 'real_value' } },
                    $ref: {},
                },
                unwantedAnotherSubProp1: {},
                unwantedAnotherSubProp2: {},
                $ref: {},
            },
        },
        unwantedSubProp3: {},
        unwantedSubProp4: {},
    },
    unwantedProp2: {},
    prop3: {
        subprop1: {
            anothersubprop1: {
                properties: { realprop: { type: 'real_value' } },
                $ref: {},
            },
        },
        subprop2: {
            anothersubprop1: {
                properties: {},
                $ref: {},
            },
            unwantedAnotherSubProp1: {},
        },
        unwantedSubProp1: {},
        unwantedSubProp2: {},
    },
    unwantedProp3: {},
    properties: { realprop: { type: 'real_value' } },
    $ref: {},
};

const saveList = new Set(["$ref", "properties"])



const treeTrim = (obj) => {
    let result = {}
    Object.keys(obj).forEach(e => {
        if (saveList.has(e)) {
            result[e] = obj[e]
        }

        else if (typeof (obj[e] == "object") && Object.keys(obj[e]).length > 0) {
            result[e] = treeTrim(obj[e])
        }
    })
    return result
}

const capitalize = (s) => {
    if (typeof s !== 'string') return ''
    return s.charAt(0).toUpperCase() + s.slice(1)
}

const formatProperties = (obj) => {
    let result = {}
    Object.keys(obj).forEach(e => {

        if (e === "properties" && Object.keys(obj[e]).length > 0) {
            if (obj[e].realprop && obj[e].realprop.type) {
                const value = obj[e].realprop.type
                let capitalizeValue = value.replace("_", " ").split(" ")
                capitalizeValue = capitalizeValue.map(e =>  { return capitalize(e) }).join(" ")
                result[e] = { realprop: value, name: capitalizeValue, size: capitalizeValue.length }
            }
            else {
                result[e] = obj[e]
            }
        }
        else if (typeof (obj[e] == "object") && Object.keys(obj[e]).length > 0) {
            result[e] = formatProperties(obj[e])
        }
    })
    return result
}

console.log(formatProperties(treeTrim(sample_object)))


推荐阅读