如何修改嵌套对象的每个值?

时间:2021-01-20 11:11:48

标签: javascript typescript

如何将此对象的每个嵌套值乘以 X(例如 0.5)?

const myObject = {
    base: {
        serving: {
            size: 100
        }
    },
    fat: {
        acids: {
            monoUnsaturatedFattyAcids: 12
            polyUnsaturatedFattyAcids: 3
            saturatedFattyAcids: 2
        },
    }
}

对象有时嵌套多达 10 层。

4 个答案:

答案 0 :(得分:1)

建议这里有一个解释:

您可以尝试类似函数的方法,该函数递归地遍历对象的属性,并根据该属性的类型,乘以或再次调用我们的递归函数。

这些是函数所采取的步骤:

  1. 我们使用 Object.keys 方法得到一个 array,其中包含我们对象的所有属性名称

  2. 我们遍历 keys 数组

  3. 对于每个 key,我们检查 obj[key] 的值是 number 还是其他值。

关于obj[key]的注意事项:通过使用方括号,您可以通过传递字符串来访问对象的属性。例如 obj['base'] 相当于 obj.base

  1. 如果它的类型确实是number,则将obj[key]乘以0.5!不要忘记将值实际分配给属性。

  2. 如果它不是 number,则再次调用该函数,但这次我们使用存储在 obj[key] 中的对象。

例如当您将 myObject 传递给函数时,第一个 key 将是 baseobj.base 包含一个对象,因此我们调用 recursiveMultiplication(obj.base) 并继续恶性循环。 直到每个 recursiveMultiplication 调用都用完要迭代的键。

当一切都完成后,原始对象应该包含变异的值。

如果您不想改变,您可以随时使用 ...spread 运算符来克隆对象并将递归函数包装在包装函数中。

const myObject = {
  base: {
    serving: {
      size: 100
    }
  },
  fat: {
    acids: {
      monoUnsaturatedFattyAcids: 12,
      polyUnsaturatedFattyAcids: 3,
      saturatedFattyAcids: 2
    }
  }
};

const recursiveMultiplication = (obj) => {
  Object.keys(obj).forEach(key => typeof obj[key] === "number" ? obj[key] = obj[key] * 0.5 : recursiveMultiplication(obj[key]))

  return obj;
};

console.log(recursiveMultiplication(myObject));

答案 1 :(得分:0)

您可以定义一个生成器,该生成器将为每个嵌套的键/值对(连同嵌套对象)提供一个迭代器,以便您可以在 for 循环中使用它做您想做的事情:

function * iter(obj) {
    for (let [key, value] of Object.entries(obj)) {
        if (Object(value) !== value) yield [obj, key, value];
        else yield * iter(value);
    }
}

// demo
const myObject = {
    base: {
        serving: {
            size: 100
        }
    },
    fat: {
        acids: {
            monoUnsaturatedFattyAcids: 12,
            polyUnsaturatedFattyAcids: 3,
            saturatedFattyAcids: 2
        },
    }
};

for (let [obj, key, value] of iter(myObject)) {
    if (typeof value === "number") obj[key] *= 0.5; // multiply by 0.5
}
// The object has been mutated accordingly
console.log(myObject);

答案 2 :(得分:0)

我认为最好是使用一个库来简化嵌套对象的遍历。

const _ = require('lodash')

const myObject = {
  base: {
      serving: {
          size: 100
      }
  },
  fat: {
      acids: {
          monoUnsaturatedFattyAcids: 12,
          polyUnsaturatedFattyAcids: 3,
          saturatedFattyAcids: 2
      },
  }
}

const newObjValue = _.cloneDeepWith(myObject, x => typeof x === 'number'? x*0.5: undefined)

console.log(newObjValue)

答案 3 :(得分:0)

这是快速解决方案。我没有为数组添加案例。如果您希望数组位于顶层或嵌套在内部,则需要添加它们。

// In App.js
import fileDownload from 'js-file-download';
import b64toBlob from 'b64-to-blob'; //importing these two in react

        axios
            .post('http://localhost:4000/file', formData)
            .then((res) => {
                const data = res.data;
                // console.log(data);
                const blob = b64toBlob(data.b64Data, data.contentType);
                // console.log(blob);
                const [ fileName ] = state.file.name.split('.');
                fileDownload(blob, `${fileName}-resized.${data.extension}`);
            })
            .catch((err) => {
                console.error(err);
            });
相关问题