Tengo un result de objeto que se puede recibir como, por ejemplo:
const firstRowVoucher = result[0]['Voucher ID'] || result[0]['voucher_id'] || result[0]['VOUCHER_ID']; const firstRowInvoice = result[0]['Invoice'] || result[0]['INVOICE'] || result[0]['invoice']; if (firstRowVoucher && firstRowInvoice){ //do some code } result.forEach((element) => { const elementVoucher = element['Voucher ID'] || result[0]['voucher_id'] || element['VOUCHER_ID']; const elementStatus = element['Invoice'] || result[0]['INVOICE'] || element['invoice']; if(elementVoucher && elementStatus){ // do some other stuff } });Funciona, pero parece un poco complicado porque hay muchas otras palabras y condicionales.
¿Hay alguna forma de verificar en una lista de names si el objeto tiene esos names como atributos? Con el fin de conseguir un mejor mantenimiento y una mejor legibilidad.
Tal vez usando una matriz de objetos o algo como esto:
const fields = { unit: ['Unit' || 'unit' || 'UNIT'], voucherID: ['Voucher ID' || 'voucher_id' || 'VOUCHER_ID'], invoice: ['Invoice' || 'INVOICE' || 'invoice'], status: ['status' || 'STATUS' || 'Status'], invoiceGrossAmount: [ 'Invoice Gross Amount' || 'Invoice_Gross_Amount' || 'invoice gross amount' || 'invoice_gross_amount', ], currency: ['Currency' || 'currency'], SupplierID: [ 'Supplier ID' || 'supplier_id' || 'Supplier_Id' || 'Supplier_ID', ], PONumber: ['PO Number' || 'PO_Number' || 'po_number' || 'po number'], status: ['status' || 'Status' || 'STATUS'], };No estoy seguro de cómo proceder.
Puede crear una pequeña función de ayuda que verifique las distintas versiones por usted para que solo tenga ese código en un solo lugar:
// pass any case example with optional space or underline function getField(obj, example) { // create canonical lowerCase version with single space delimiters const exSpace = example.replace(/\s+|_+/g, " ").toLowerCase(); let props = Object.entries(obj); for (let propName of props) { // take candicate property name and convert it to canonical // form of lowercase, space delimited, spaces and underscores collapsed const propCanonical = propName.toLowerCase().replace(/\s+|_+/g, " "); if (propCanonical === exSpace) { return obj[propName]; } } return null; }Y luego úsalo así:
const firstRowVoucher = getField(result[0], 'Voucher ID'); const firstRowInvoice = getField(result[0], 'Invoice'); Para su información, el hecho de que no sepa cuál es la forma del nombre del campo parece un código incorrecto en algún lugar anterior a este que debe limpiarse. Si realmente no tiene control sobre la calidad de la entrada, entonces tal vez debería desinfectar toda la entrada antes de manipularla, de modo que una vez que obtenga el result , solo use nombres de campo estandarizados.
Recomendaría transformar sus objetos de resultado en un formato específico. Una forma de lograr esto sería configurar todas sus claves para snake_case
const snakeCaseResults = result.map((obj) => Object.entries(obj).reduce( (res, [key, value]) => ({ ...res, [key.toLowerCase().replaceAll(' ', '_')]: value }), {} ) )de esta manera, siempre puede acceder a su resultado usando snake_case
P.ej
const firstRowVoucher = snakeCaseResults[0]['voucher_id']; const firstRowInvoice = snakeCaseResults[0]['invoice'];