Recently, I conducted a brief code review with the project team, and found that there were many aspects in the team members, such as redundant codes, too much name-based programming and little use of functional programming. Therefore, I began to think about how to help the team members improve these aspects. Now, I will briefly talk about a few areas that I found that can be improved

Range values correspond to single values

Example description: obtain a single icon value based on the range of fileSuffix fileSuffix

// File suffix
const fileSuffix = 'ppt'

// Create the mapping
const map = {
    "xls": ["xls"."xlsx"."xlsm"]."doc": ["doc"."docx"]."ppt": ["ppt"."pptx"]."pdf": ["pdf"]."audio": ["mp3"."wma"]."media": ["mp4"]."zip": ["zip"."7z"."rar"."apz"]."txt": ["txt"]."image": ["jpg"."jpeg"."gif"."png"]}// Some friends may or for in loop object judgment
// A few implementations might go something like this
const icon = Object.keys(map)[Object.values(map).findIndex(i= > i.includes(fileSuffix))] || 'default'
Copy the code

Consider: If we now have a scenario where multiple range values correspond to a single value, which can be either a string or a function, and we need to return a default value or execute a default function if the value passed is not in the range, what do we do

The sample

// File suffix
const fileSuffix = 'ppt'
const defaultFn = () = >{}

 // If fileSuffix belongs to [" XLS ", "XLSX "," XLSM "], return "XLS"
 // If fileSuffix belongs to ["zip"], return the result of the logical processing, otherwise execute the default function
 
 if(["xls"."xlsx"."xlsm"].includes(fileSuffix)){
     return "xls"
 }else if(["zip"].includes(fileSuffix)){
     // all kinds of logic processing...
     return "The result of various logical processes."
 }
 // If else is not easy to maintain
Copy the code

Some people may think of Map, because any value (object or original value) can be used as a key, but I still don’t want to use Map to implement, please forgive my stubbornness

Further thinking and optimization, three data types were created, all of which needed to be compatible

// File suffix
const fileSuffix = 'ppt'

// Create data type 1, fileSuffix only belong to the corresponding key parsed array, return the corresponding string value
const type1 = {
    '["xls", "xlsx", "xlsm"]':"xls".'["doc", "docx"]':"doc".'["ppt", "pptx"]':"ppt".'["pdf"]':"pdf".'["mp3", "wma"]':"audio".'["mp4"]':"media".'["zip", "7z", "rar", "apz"]':"zip".'["txt"]':"txt".'["jpg", "jpeg", "gif", "png"]':"image"
}

// Create data type 2, fileSuffix only belong to the corresponding key parsed array, return the value returned by the corresponding function
const type2 = {
    '["xls", "xlsx", "xlsm"]':() = >{
        // all kinds of logic processing...
        return "The result of various logical processes."+"xls"
    },
    '["doc", "docx"]':() = >{
         // all kinds of logic processing...
        return "The result of various logical processes."+"doc"
    },
    '["ppt", "pptx"]':() = >{
           // all kinds of logic processing...
        return "The result of various logical processes."+"ppt"
    },
    '["pdf"]':() = >{
          // all kinds of logic processing...
        return "The result of various logical processes."+"pdf"
    },
    '["mp3", "wma"]':() = >{
          // all kinds of logic processing...
        return "The result of various logical processes."+"audio"
    },
    '["mp4"]':() = >{
          // all kinds of logic processing...
        return "The result of various logical processes."+"media"
    },
    '["zip", "7z", "rar", "apz"]':() = >{
          // all kinds of logic processing...
        return "The result of various logical processes."+"zip"
    },
    '["txt"]':() = >{
          // all kinds of logic processing...
        return "The result of various logical processes."+"txt"
    },
    '["jpg", "jpeg", "gif", "png"]':() = >{
          // all kinds of logic processing...
        return "The result of various logical processes."+"image"}}// Create data type 3, fileSuffix only belong to the corresponding key parsed array, return the corresponding string value or return the corresponding function value
const type3 = {
    '["xls", "xlsx", "xlsm"]':"xls".'["doc", "docx"]':"doc".'["ppt", "pptx"]':"ppt".'["pdf"]':"pdf".'["mp3", "wma"]':() = >{
       // all kinds of logic processing...
        return "The result of various logical processes."+"audio"
    },
    '["mp4"]':"media".'["zip", "7z", "rar", "apz"]':"zip".'["txt"]':"txt".'["jpg", "jpeg", "gif", "png"]':() = >{
        // all kinds of logic processing...
        return "The result of various logical processes."+"image"}}Copy the code

In fact, there are many such requirements in real projects, and object handling is also the best way to simplify if else. We use a function to accommodate these scenarios, PS: the property values of the key type of our Map object only support arrays and strings

/ * * *@description: Simplifies function key to array string *@param { Object } O: Like the above three objects *@param { String } S: key string * like the above three objects@param { String | Function } D: Does not match the given default value or the executed default function */
function simplify(o, s, d){

    // Check whether the corresponding key can be found

    const k = Object.keys(o).find(k= > JSON.parse(k).includes(s))

    // If it is found and the corresponding value is a string, then the string is returned directly

    if(typeof o[k] ==='string')return o[k]

    // If it is found and the corresponding value is a function, execute it directly

    if(typeof o[k] === 'function')return o[k]()

    // If not found and default d is a string, default d is returned

    if(! o[k] && d &&typeof d ==='string')return d

    // If not found and default d is a function, then execute directly

    if(! o[k] && d &&typeof d === 'function') return d()

}
// How to use it
// Return 'default' if type1 is not matched to 'wma', return matching value if type1 is matched
simplify(type1,'wma'.'default')


simplify(type1,'wma1'.() = >{
    // There is no match to execute the default function
    console.log('There is no match to execute this default function')})Copy the code

if

Here’s the code. Here’s the code

const a = 1
const b = 1
const c = 1

if (a === 1) {
    if (b === 1) {
        if (c === 1) {
            return 'a1-b1-c1'
        } else if (c === 2) {
            return 'a1-b1-c2'
        } else {
            return 'a1-b1-else'}}else if (b === 2) {
        if (c === 1) {
            return 'a1-b2-c1'
        } else if (c === 2) {
            return 'a1-b2-c2'
        } else {
            return 'a1-b2-else'}}else {
        if (c === 1) {
            return 'a1-else-c1'
        } else if (c === 2) {
            return 'a1-else-c2'
        } else {
            return 'a1-else-else'}}}else if (a === 2) {
    if (b === 1) {
        if (c === 1) {
            return 'a2-b1-c1'
        } else if (c === 2) {
            return 'a2-b1-c2'
        } else {
            return 'a2-b1-else'}}else if (b === 2) {
        if (c === 1) {
            return 'a2-b2-c1'
        } else if (c === 2) {
            return 'a2-b2-c2'
        } else {
            return 'a2-b2-else'}}else {
        if (c === 1) {
            return 'a2-else-c1'
        } else if (c === 2) {
            return 'a2-else-c2'
        } else {
            return 'a2-else-else'}}}else {
    if (b === 1) {
        if (c === 1) {
            return 'else-b1-c1'
        } else if (c === 2) {
            return 'else-b1-c2'
        } else {
            return 'else-b1-else'}}else if (b === 2) {
        if (c === 1) {
            return 'else-b2-c1'
        } else if (c === 2) {
            return 'else-b2-c2'
        } else {
            return 'else-b2c-else'}}else {
        if (c === 1) {
            return 'else-else-c1'
        } else if (c === 2) {
            return 'else-else-c2'
        } else {
            return 'else-else-else'}}}Copy the code

The above is just a few conditions, if there are many will become very cumbersome, difficult to maintain, so let’s flatten the above code and have a look

const a = 1
const b = 1
const c = 1

const elseValue = 99 // else The value is 99 and can be customized

if(a===1 && b===1 && c===1) {return 'a1-b1-c1'
}else if(a===1 && b===1 && c===2) {return 'a1-b1-c2'
}else if(a===1 && b===1 && c===elseValue){
    return 'a1-b1-else'
} else if(a===1 && b===2 && c===1) {return 'a1-b2-c1'
}else if(a===1 && b===2 && c===2) {return 'a1-b2-c2'
}else if(a===1 && b===2 && c===elseValue){
    return 'a1-b2-else'
} else if(a===1 && b===elseValue && c===1) {return 'a1-else-c1'
}else if(a===1 && b===elseValue && c===2) {return 'a1-else-c2'
}else if(a===1 && b===elseValue && c===elseValue){
    return 'a1-else-else'
}
else 

if(a===2 && b===1 && c===1) {return 'a2-b1-c1'
}else if(a===2 && b===1 && c===2) {return 'a2-b1-c2'
}else if(a===2 && b===1 && c===elseValue){
    return 'a2-b1-else'
} else if(a===2 && b===2 && c===1) {return 'a2-b2-c1'
}else if(a===2 && b===2 && c===2) {return 'a2-b2-c2'
}else if(a===2 && b===2 && c===elseValue){
    return 'a2-b2-else'
} else if(a===2 && b===elseValue && c===1) {return 'a2-else-c1'
}else if(a===2 && b===elseValue && c===2) {return 'a2-else-c2'
}else if(a===2 && b===elseValue && c===elseValue){
    return 'a2-else-else'
}

else

if(a===elseValue && b===1 && c===1) {return 'else-b1-c1'
}else if(a==elseValue && b===1 && c===2) {return 'else-b1-c2'
}else if(a===elseValue && b===1 && c===elseValue){
    return 'else-b1-else'
} else if(a===elseValue && b===2 && c===1) {return 'else-b2-c1'
}else if(a===elseValue && b===2 && c===2) {return 'else-b2-c2'
}else if(a===elseValue && b===2 && c===elseValue){
    return 'else-b2-else'
} else if(a===elseValue && b===elseValue && c===1) {return 'else-else-c1'
}else if(a===elseValue && b===elseValue && c===2) {return 'else-else-c2'
}else if(a===elseValue && b===elseValue && c===elseValue){
    return 'else-else-else'
}
Copy the code

Let’s go further and optimize

const a = 1
const b = 1
const c = 1

const ValidValue = [1.2]
const elseValue = 99

// Enumerations of a, B, and C can only be 1 or 2 as agreed, even if they need to be added later, we can easily add them in the map object, it is more convenient to manage and maintain an object, else we identify as 99, you can define other

// We create an object to maintain an object

const map = {
     '{"a":1,"b":1,"c":1}':() = >'a1-b1-c1'.'{"a":1,"b":1,"c":2}':() = >'a1-b1-c2'.'{"a":1,"b":1,"c":99}':() = >'a1-b1-else'.'{"a":1,"b":2,"c":1}':() = >'a1-b2-c1'.'{"a":1,"b":2,"c":2}':() = >'a1-b2-c2'.'{"a":1,"b":2,"c":99}':() = >'a1-b2-else'.'{"a":1,"b":99,"c":1}':() = >'a1-else-c1'.'{"a":1,"b":99,"c":2}':() = >'a1-else-c2'.'{"a":1,"b":99,"c":99}':() = >'a1-else-else'.'{"a":2,"b":1,"c":1}':() = >'a2-b1-c1'.'{"a":2,"b":1,"c":2}':() = >'a2-b1-c2'.'{"a":2,"b":1,"c":99}':() = >'a2-b1-else'.'{"a":2,"b":2,"c":1}':() = >'a2-b2-c1'.'{"a":2,"b":2,"c":2}':() = >'a2-b2-c2'.'{"a":2,"b":2,"c":99}':() = >'a2-b2-else'.'{"a":2,"b":99,"c":1}':() = >'a2-else-c1'.'{"a":2,"b":99,"c":2}':() = >'a2-else-c2'.'{"a":2,"b":99,"c":99}':() = >'a2-else-else'.'{"a":99,"b":1,"c":1}':() = >'else-b1-c1'.'{"a":99,"b":1,"c":2}':() = >'else-b1-c2'.'{"a":99,"b":1,"c":99}':() = >'else-b1-else'.'{"a":99,"b":2,"c":1}':() = >'else-b2-c1'.'{"a":99,"b":2,"c":2}':() = >'else-b2-c2'.'{"a":99,"b":2,"c":99}':() = >'else-b2-else'.'{"a":99,"b":99,"c":1}':() = >'else-else-c1'.'{"a":99,"b":99,"c":2}':() = >'else-else-c2'.'{"a":99,"b":99,"c":99}':() = >'else-else-else',}You can also write the map key like this
/* const map = { [JSON.stringify({a:1,b:1,c:1})]:()=>'a1-b1-c1' } */
/ * *@description: Simplifies function object key to object string *@param { Object } O: object map *@param { Object } C: Conditional object *@param { String | Function } D: Does not match the given default value or the executed default function */
 const simplifyFunc = function (o, c, d) {
    const keys = Object.keys(o)
    if(! keys.length)throw Error('Do not accept empty objects')
    const index = keys.findIndex(i= > JSON.stringify(JSON.parse(i)) === JSON.stringify(c))
    const val = o[keys[index]]
    if (typeof val === 'string') return val
    if (typeof val === 'function') return val()
    if(! val &&typeof d === 'string') return d
    if(! val &&typeof d === 'function') return d()
}

simplifyFunc(map,{ 
    a:ValidValue.includes(a)? a:elseValue,b:ValidValue.includes(b)? a:elseValue,c:ValidValue.includes(c)? a:elseValue })Copy the code

The core principle of these two code simplifications is to create an object whose key is converted to an array of strings or string objects, and it’s much easier to maintain one object than a bunch of if and else

switch

The first instinct for switch optimization should be the object, but it depends

function previewWeek(i){
    switch(i){
        case 1:
            return 'Monday'
            break;
        case 2:
            return 'Tuesday'
            break;
        case 3:
            return 'Wednesday'
            break;  
        case 4:
            return 'Thursday'
            break;  
        case 5:
            return 'Friday'
            break;  
        case 6:
            return 'Saturday'
            break;  
        case 7:
            return 'Sunday'
            break;
        default:
            return ' '}}Copy the code

Optimize with object form

function previewWeek(i){
    return ({
        1:'Monday'.2:'Tuesday'.3:'Wednesday'.4:'Thursday'.5:'Friday'.6:'Saturday'.7:'Sunday',
    })[i] || ' '
}
Copy the code

It’s different, it’s actually a lot less code, but if you look at the characteristics of it, you can optimize it without using an object, and that’s the rule, and the key values are all the same, and the value of 1 is Monday, it’s all 1, and it’s related to the index, so the index is related to the array, so let’s try using the array

function previewWeek(i){
    return  i>0 && i<8 ?'week'+ ['一'.'二'.'三'.'four'.'five'.'六'.'day'][i-1] :' '
}
Copy the code

So we’ve learned that there are many ways, but we haven’t found the right one, so let’s write it here. Thank you for reading, and if it worked for you, give it a thumbs up

conclusion

If you have a better idea, please leave a comment

Please point out any inaccuracies or errors in the article