繁体   English   中英

条件解构

[英]Conditional destructuring

我正在尝试有条件地解构 object,但即使尝试实现我在此处的其他答案中看到的后备也无济于事。 有时出发或到达都未定义,这会导致代码中断。 我该如何解决?

const {
    duration,
    segments: [
        {
            departure: { iataCode: departureIataCode, at: departAt},
            arrival: { iataCode: arrivalIataCode, at: arriveAt },
            carrierCode,
        },
        {
            departure: {
                iataCode: stopOverDepartureIataCode,
                at: stopOverDepartAt,
            },
            arrival: { iataCode: finalArrivalIataCode, at: finalArriveAt },
        },
    ],
} = outbound;

这可能不是一个直接的答案,但肯定与某些人相关且有帮助......

我在 Laravel data_get() php function 的启发下创建了这个 function:

/**
 * Get an item from an array or object using "dot" notation.
 *
 * @param {object} source
 * @param {array|string} name
 * @param {null|*} defaultValue
 *
 * @returns {null|*}
 */
window.objectGet = function( source, name, defaultValue = null ) {

    const parts = Array.isArray( name ) ? name : name.split( '.' );

    // Duplicate array prevents modifying original by reference
    let partsTracking = Array.isArray( name ) ? name : name.split( '.' );

    for ( let i = 0; i < parts.length; i++ ) {
        const segment = parts[ i ];
        partsTracking.splice( 0, 1 );

        if ( segment === null ) {
            return source;
        }

        if ( segment === '*' ) {

            if ( !source || typeof source !== 'object' ) {
                return defaultValue;
            }

            let tmpResult = [];

            for ( var key in source ) {
                tmpResult.push( objectGet( source[ key ], partsTracking.join( '.' ), defaultValue ) );
            }

            return partsTracking.includes( '*' ) ? tmpResult.flat( Infinity ) : tmpResult;
        }

        if ( source && typeof source === 'object' && segment in source ) {
            source = source[ segment ];
        } else {
            return defaultValue;
        }
    }

    return source;
};

示例用法:

const myObject = {
    key: 'value',
    nested: {
        example: [
            'value1',
            'value2',
        ]
    }
};

console.log( objectGet( myObject, 'key' ) ); // Output: 'value'
console.log( objectGet( myObject, 'nested.example' ) ); // Output: [ 'value1', 'value2' ]
console.log( objectGet( myObject, 'nested.example.0' ) ); // Output: 'value1'
console.log( objectGet( myObject, 'nested.example.1' ) ); // Output: 'value2'

因此,关于 OPs 问题的用法可能类似于:

const duration                  = objectGet( outbound, 'duration' );
const departureIataCode         = objectGet( outbound, 'segments.0.departure.iataCode' );
const departAt                  = objectGet( outbound, 'segments.0.departure.at' );
const arrivalIataCode           = objectGet( outbound, 'segments.0.arrival.iataCode' );
const arriveAt                  = objectGet( outbound, 'segments.0.arrival.at' );
const carrierCode               = objectGet( outbound, 'segments.0.carrierCode' );
const stopOverDepartureIataCode = objectGet( outbound, 'segments.1.departure.iataCode' );
const stopOverDepartAt          = objectGet( outbound, 'segments.1.departure.at' );
const finalArrivalIataCode      = objectGet( outbound, 'segments.1.arrival.iataCode' );
const finalArriveAt             = objectGet( outbound, 'segments.1.arrival.at' );

我应该补充一点,如果找不到密钥,将返回 null。 您可以将默认值作为第三个参数传递,例如:

const notFound = objectGet( input, 'my.data.key', 'my default value' );

您还可以使用*返回一个嵌套值数组,例如:

const input = {
    data: [
        {
            id: 123,
            name: 'Example 1'
        },
        {
            id: 789,
            name: 'Example 2'
        }
    ]
};

const ids = objectGet( input, 'data.*.id' ); // Ouput: [ 123, 789 ]

如果在解构时提供默认值,则不会出现错误,而是将值设置为某个默认值(如果不存在)。

在下面的示例中,我从第一段中删除了到达 object 和停止 iata 代码,这些将设置为默认值而不是导致错误。

 let outbound = { duration: 'duration', segments: [ { departure: { iataCode: 'LAX', at: 'departAt'}, carrierCode: 'LH', }, { departure: { at: 'stopOverDepartAt', }, arrival: { iataCode: 'finalArrivalIataCode', at: 'finalArriveAt' }, }, ], }; // Set to whichever value you wish... const defaultValue = undefined; const { duration, segments: [ { departure: { iataCode: departureIataCode = defaultValue, at: departAt = defaultValue } = {}, arrival: { iataCode: arrivalIataCode = defaultValue, at: arriveAt = defaultValue } = {}, carrierCode = '', } = {}, // Set default for segment 0. { departure: { iataCode: stopOverDepartureIataCode = defaultValue, at: stopOverDepartAt = defaultValue, } = {}, arrival: { iataCode: finalArrivalIataCode = defaultValue, at: finalArriveAt = defaultValue } = {}, } = {}, // Set default for segment 1. ] = [{},{}], // Set defaults for segments. } = outbound; let outputs = { departureIataCode, carrierCode, arrivalIataCode, stopOverDepartureIataCode }; Object.keys(outputs).forEach(k => console.log(`${k}:`, `${outputs[k]}`))
 .as-console-wrapper { max-height: 100%;important: top; 0; }

我还要看看lodash get ,这对于访问可能存在或不存在的嵌套值非常有用:

 let outbound = { duration: 'duration', segments: [ { departure: { iataCode: 'LAX', at: 'departAt'}, carrierCode: 'LH', }, { departure: { at: 'stopOverDepartAt', }, arrival: { iataCode: 'finalArrivalIataCode', at: 'finalArriveAt' }, }, ], }; let departureIataCode = _.get(outbound, 'segments[0].departure.iataCode'); let carrierCode = _.get(outbound, 'segments[0].carrierCode'); let arrivalIataCode = _.get(outbound, 'segments[0].arrival.iataCode'); let stopOverDepartureIataCode = _.get(outbound, 'segments[1].departure.iataCode'); let outputs = { departureIataCode, carrierCode, arrivalIataCode, stopOverDepartureIataCode }; Object.keys(outputs).forEach(k => console.log(`${k}:`, `${outputs[k]}`))
 .as-console-wrapper { max-height: 100%;important: top; 0; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" referrerpolicy="no-referrer"></script>

暂无
暂无

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

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