纯Javascript -根据用户输入选择未知对象的属性,用户输入的字段希望包含在输出中,而不包含任何库

ttp71kqs  于 2023-01-24  发布在  Java
关注(0)|答案(1)|浏览(113)

我有一个对象,用户应该只能选择他/她想要的属性。
下面是用户可以筛选的对象的示例;

const responseObject = {
  name: 'John Doe',
  age: 25,
  cars: [
     {
         name: "Test car",
         brand: "Test brand",
         accessories: [
             {
                 name: "Test accessory",
                 description: "Test description",
                 code: "1234"
             },
             {
                 name: "Test accessory",
                 description: "Test description",
                 code: "12345"
             }
        ]
     },
     {
         name: "Test car 2",
         brand: "Test brand 2",
         accessories: [
             {
                 name: "Test accessory 2",
                 description: "Test description 2",
                 code: "1234"
             },
             {
                 name: "Test accessory 2",
                 description: "Test description",
                 code: "12345"
             }
        ]
     }
    ]
};

下面是一个用户请求的示例,其中包含他/她希望包含在响应中的字段。它的工作原理类似于select(SELECT name, cars.name, cars.accessories FROM ....

const includedFields = {
    fields: [
        "name",
        "cars.name",
        "cars.accessories."
    ]
};

这是预期的输出。代码应该只获取用户请求中包含的字段,忽略输入对象中的所有其他字段。此对象将来自API:

const changedResponse = {
  name: 'John Doe',
  cars: [
     {
         name: "Test car",
         accessories: [
             {
                 name: "Test accessory",
             },
             {
                 name: "Test accessory",
             }
        ]
     },
     {
         name: "Test car 2",
         accessories: [
             {
                 name: "Test accessory 2"
             },
             {
                 name: "Test accessory 2"
             }
        ]
     }
    ]
};

我创建这个函数就是为了解决这个问题,我循环遍历所有的字段,检查它们是否在数组中,如果不在,我会在输出中设置它们,如果在,我不知道该怎么做。

function filterResponseFields(fieldsFilter, inputObject) { 
 const response = {};
 for(let i = 0; i < fieldsFilter.length; i++) {
   let fieldPath = fieldsFilter[i];
   let fieldPathAttributes = filter.split(".");
   let fieldsInsideArrays = [];
   let containsFieldIsInsideArray = false;
   let currentAttributePath = '';
   
   for(let j = 0; j < fieldsFilter.length; j++) {
       
    currentAttributePath = currentAttributePath ? fieldPathAttributes[j] : currentAttributePath + "." + fieldPathAttributes[j];
    if (Array.isArray(inputObject[currentAttributePath])) {
        containsFieldIsInsideArray = true;
        fieldsInsideArrays.push({
           path: currentAttributePath,
           filterField: filter
        });
    }
   }
   
   if (!containsFieldIsInsideArray) {
       response[field] = inputObject[field];
   } else {
       // I DO NOT KNOW WHAT TO DO HERE
   }
}
eeq64g8w

eeq64g8w1#

您可以使用js Object.keys方法获取对象的所有键,然后递归调用这些键,将嵌套的键作为后缀附加,如下所示:

const responseObject = {
    name: 'Jhon Doe',
    age: 25,
    cars: [
       {
           name: "Test car",
           brand: "Test brand",
           acessories: [
               {
                   name: "Test acessory",
                   description: "Test description",
                   code: "1234"
               },
               {
                   name: "Test acessory",
                   description: "Test description",
                   code: "12345"
               }
          ]
       },
       {
           name: "Test car 2",
           brand: "Test brand 2",
           acessories: [
               {
                   name: "Test acessory 2",
                   description: "Test description 2",
                   code: "1234"
               },
               {
                   name: "Test acessory 2",
                   description: "Test description",
                   code: "12345"
               }
          ]
       }
    ]
};
  
const filterResponseFields = rawResponse => {
    const getFields = obj => Object.keys(obj).flatMap(key => {
        const value = obj[key]

        if (Array.isArray(value)) return value.length === 0 ? [] : getFields(value[0]).map(e => `${ key }.${ e }`)

        return typeof value === 'object' ? getFields(value).map(e => `${ key }.${ e }`) : key
    })

    const fields = getFields(rawResponse)

    return {
        fields
    }
}

console.log(filterResponseFields(responseObject))

顺便说一下,如果您希望用户只拥有一些键,则可以过滤fields数组。

相关问题