简体   繁体   English

将 object 嵌套属性转换为新类型

[英]Cast object nested properties to new type

I previously made a general purpose function that recursively cast nested property values into number:我之前做了一个通用的 function 递归地将嵌套属性值转换为数字:

type CastToNumber<T> = T extends string ? number : {
    [K in keyof T]: CastToNumber<T[K]>
};

type StringMap = { [key: string]: any };

const castObjectValuesToNumber = function<T extends StringMap, K extends keyof T>(initialObj: T, nestedProp?: string): CastToNumber<T> {

    let _castedObj: StringMap = {};

    for(const [property, value] of Object.entries(initialObj)) {
        if(typeof(value) === "object") {

            const newVal = castObjectValuesToNumber(value, property) as CastToNumber<T>;
            _castedObj = { ..._castedObj, ...newVal };

        } else {

            if(nestedProp) {
                if(!_castedObj[nestedProp]) _castedObj[nestedProp] = {};
                _castedObj[nestedProp][property] = +value;
            } else {
                _castedObj[property] = +value;
            }

        }
    }
    return _castedObj as CastToNumber<T[K]>;
}

This was working well for most objects but I recently had to cast this object and it didn't work.这对大多数对象都很有效,但我最近不得不投射这个 object 并且它不起作用。

const army = {
    cavalry: {
      light: { quantity: "0", health: "0" },
      heavy: { quantity: "0", health: "0" }
    },
    infantry: {
      light: { quantity: "0", health: "0" },
      heavy: { quantity: "0", health: "0" }
    },
    magic: {
      light: { quantity: "0", health: "0" },
      heavy: { quantity: "30", health: "0" }
    },
    range: {
      light: { quantity: "0", health: "0" },
      heavy: { quantity: "0", health: "0" }
    }
};

const result = castObjectValuesToNumber(army);

/*
result = {
    light: { quantity: 0, health: 0 },
    heavy: { quantity: 0, health: 0 }
  };

wanted = {
  cavalry: {
    light: { quantity: 0, health: 0 },
    heavy: { quantity: 0, health: 0 }
  },
  infantry: {
    light: { quantity: 0, health: 0 },
    heavy: { quantity: 0, health: 0 }
  },
  magic: {
    light: { quantity: 0, health: 0 },
    heavy: { quantity: 30, health: 0 }
  },
  range: {
    light: { quantity: 0, health: 0 },
    heavy: { quantity: 0, health: 0 }
  }
}
*/

It is only returning a limited scope of nested properties, because it doesn't properly store properties and recursively set them.它只返回有限的 scope 嵌套属性,因为它没有正确存储属性并递归设置它们。 I can't find a way to make this function work for deeply nested properties.我找不到让这个 function 适用于深度嵌套属性的方法。

_castedObj = { ..._castedObj, ...newVal };

should be应该

_castedObj[property] = newVal;

it is a simple recursive function to iterate an object.它是一个简单的递归 function 来迭代 object。

 const army = {cavalry:{light:{quantity:"0",health:"0"},heavy:{quantity:"0",health:"0"}},infantry:{light:{quantity:"0",health:"0"},heavy:{quantity:"0",health:"0"}},magic:{light:{quantity:"0",health:"0"},heavy:{quantity:"30",health:"0"}},range:{light:{quantity:"0",health:"0"},heavy:{quantity:"0",health:"0"}}}; function iterate(obj) { Object.keys(obj).forEach(function(key) { var value = obj[key]; if (typeof value === 'object' && value;= null) { iterate(value) } if (typeof value === "string") { obj[key] = +value. } }) } iterate(army) console.log(army)
 .as-console-wrapper {max-height: 100% !important}

Here's a simple version, which recursively maps a function over an object/array/other structure:这是一个简单的版本,它递归地将 function 映射到对象/数组/其他结构上:

 const deepMap = (fn) => (o) => Array.isArray (o)? o.map (deepMap (fn)): Object (o) === o? Object.fromEntries (Object.entries (o).map (([k, v]) => [k, deepMap (fn) (v)])): fn (o) const army = {cavalry: {light: {quantity: "0", health: "0"}, heavy: {quantity: "0", health: "0"}}, infantry: {light: {quantity: "0", health: "0"}, heavy: {quantity: "0", health: "0"}}, magic: {light: {quantity: "0", health: "0"}, heavy: {quantity: "30", health: "0"}}, range: {light: {quantity: "0", health: "0"}, heavy: {quantity: "0", health: "0"}}} console.log (deepMap (Number) (army))
 .as-console-wrapper {max-height: 100%;important: top: 0}

Here we call it with the Number constructor, but we could map using anything.这里我们用Number构造函数调用它,但我们可以使用任何东西 map。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM