首页 > 解决方案 > 如何使用通过参数传递的函数来格式化给定的必填字段的复杂对象?

问题描述

我正在尝试创建一个函数,该函数通过复杂对象格式化数组中的给定字段。

该函数必须接收必须格式化的对象,然后下一个参数是具有必须格式化的属性的数组,最后一个函数接收将格式化字段值的函数。

该函数必须以其原始结构返回对象。

到目前为止我的代码:

const formatFields = (obj = {}) => (fieldsToFormat = []) => (formatFunction = () => {}) => {
   let newObj = { ...obj };
   for (let [k, v] of Object.entries(obj)) {
      if (typeof v === 'object' && v !== null) formatFields(v)(fieldsToFormat)(formatFunction);
      if (fieldsToFormat.includes(k)) newObj = { ...newObj, [k]: formatFunction(v) };
      else newObj = { ...newObj, [k]: v };
   }
   return newObj;
}

const toMoney = (num) => '$' + num;

const obj = { 
    totalAmount: 83.24,
    quoteItems: 
       [ { max: '1',
           code: '1',
           quantity: 1,
           unitPrice: 23.21,
           totalPrice: 23.21,
           description: 'test' 
         },{ 
           max: '3',
           code: '2',
           quantity: 3,
           unitPrice: 20.01,
           totalPrice: 60.03,
           description: 'test2' 
       } ],
};

const priceFormatAttributes = [
    'unitPrice', 
    'totalPrice', 
    'totalAmount'
];

console.log(formatFields(obj)(priceFormatAttributes)(toMoney));

嵌套对象未格式化!

我知道这是一个合乎逻辑的问题……它具有挑战性,我无法继续前进。

我认为递归是错误的,但我不明白为什么!

如果有人知道如何以另一种方式解决这个问题,也欢迎。

标签: javascriptfunctional-programminglogic

解决方案


虽然我不确定预期的输出是什么,但我会试试这个:

const formatFields = (obj = {}) => (fieldsToFormat = []) => (formatFunction = () => {}) => {
    let newObj = { ...obj }; // clone object to prevent changing the original object
    if (Array.isArray(obj)) { // gotta deal with arrays too unless you want to change them all into objects
        newObj = [ ...obj ];
    }

    for (let [key, value] of Object.entries(obj)) {
        if (Array.isArray(newObj)) {
            newObj.splice(key - 1, 1); // remove the previous it
            newObj.push(formatFields(value)(fieldsToFormat)(formatFunction));
        }
        else if (typeof value === 'object' && value !== null) {
            newObj = { ...newObj, [key]: formatFields(value)(fieldsToFormat)(formatFunction) };
        }
        else if (fieldsToFormat.includes(key)) {
            newObj[key] = formatFunction(value)
        }
        else newObj = { ...newObj, [key]: value };
    }

    return newObj;
}

const toMoney = (num) => {
    return '$' + num;
}

const obj = {
    totalAmount: 83.24,
    quoteItems: [
        {
            max: '1',
            code: '1',
            quantity: 1,
            unitPrice: 23.21,
            totalPrice: 23.21,
            description: 'test',
        },
        {
            max: '3',
            code: '2',
            quantity: 3,
            unitPrice: 20.01,
            totalPrice: 60.03,
            description: 'test2',
        }
    ],
};

const priceFormatAttributes = [
    'unitPrice',
    'totalPrice',
    'totalAmount',
];

console.log(formatFields(obj)(priceFormatAttributes)(toMoney));

这输出:

{
  totalAmount: '$83.24',
  quoteItems: [
    {
      max: '1',
      code: '1',
      quantity: 1,
      unitPrice: '$23.21',
      totalPrice: '$23.21',
      description: 'test'
    },
    {
      max: '3',
      code: '2',
      quantity: 3,
      unitPrice: '$20.01',
      totalPrice: '$60.03',
      description: 'test2'
    }
  ]
}

推荐阅读