简体   繁体   English

条件解构

[英]Conditional destructuring

I am trying to destructure an object conditionally but even trying to implement fallbacks I saw on other answers on here doesn't help.我正在尝试有条件地解构 object,但即使尝试实现我在此处的其他答案中看到的后备也无济于事。 Sometimes either departure or arrival are undefined which makes the code break.有时出发或到达都未定义,这会导致代码中断。 How could I solve it?我该如何解决?

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;

This might not be a direct answer but is definitely related and helpful to some...这可能不是一个直接的答案,但肯定与某些人相关且有帮助......

I created this function a while back inspired by Laravels data_get() php function:我在 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;
};

Example usage:示例用法:

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'

So usage in regards to OPs question might be something like:因此,关于 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' );

I should add that if a key isn't found, null will be returned.我应该补充一点,如果找不到密钥,将返回 null。 You can pass default values as the third parameter, for example:您可以将默认值作为第三个参数传递,例如:

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

You can also return an array of nest values by using * for example:您还可以使用*返回一个嵌套值数组,例如:

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

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

If you provide defaults when destructuring, you won't get an error, rather the values will be set to some default value if not present.如果在解构时提供默认值,则不会出现错误,而是将值设置为某个默认值(如果不存在)。

In the example below I've removed the arrival object from the first segment and the stop over iata code, these will be set to the default value rather than causing an error.在下面的示例中,我从第一段中删除了到达 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; }

I'd also take a look at lodash get , this is very good for accessing nested values that may or may not be present:我还要看看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