首页 > 解决方案 > 在接受数字或数组作为参数的函数内部,如何有效地操作这些参数而不管类型如何?

问题描述

想象一下,您有一个函数接受 1D 坐标、2D 坐标或 3D 坐标作为参数。在函数调用中,如果用户想要传递一些一维坐标,他们会传递简单的数字,例如:

myFunction(30, 50);

但如果他们想传递 2D 或 3D 坐标,他们会将这些坐标作为数组/向量值传递,例如:

myFunction([30, 40], [50, 60]);

现在,在函数定义中,假设您要运行涉及传递坐标的各种操作和方程。因为您需要处理两种不同的 arg 类型(数字与数组)中的一种,所以您可能希望为每种数据类型设置不同的语句格式,因此您最终可能会重复一堆语句,这是低效的。为了论证起见,假设您不能对数组 args 进行简单的向量数学运算,而是需要循环并按索引将它们分解:

function myFunction( coord1, coord2 ) {
    let myVar1 = 0, myVar2 = 0, myVar3 = 0;

    // if args are arrays
    if ( Array.isArray( coord1 ) ) {
        myVar1 = [], myVar2 = [], myVar3 = [];

        for (let i = 0; i < coord1.length; i++) {
            myVar1[i] = coord1[i] * coord2[i];
            myVar2[i] = myVar1[i] / coord2[i] + myVar1[i];
            myVar3[i] = coord1[i] * (coord2[i] / myVar2[i]);
        }

    // else if args are scalar
    } else {
        myVar1 = coord1 * coord2;            // this
        myVar2 = myVar1 / coord2 + myVar1;   // is
        myVar3 = coord1 * (coord2 / myVar2); // inefficient
    }

    return myVar3;
}

上面的方程式是胡说八道,但它们只是为了说明。您将如何避免在这里重复自己?我可以想到几种 DRY 方法(将标量 args 分配给单索引数组;或将方程式的块变成混乱且难以阅读的“逻辑或”表达式(例如,myVar[i] = (coord1[i] || coord1) * (coord2[i] || coord2));或装配一组对象什么的),但我真的不喜欢他们中的任何一个,而且我还是个新手,所以我不知道它是什么我不知道。任何有经验的编码人员都想权衡处理此类情况的最佳实践吗?

标签: javascript

解决方案


对于逐元素重复,只需让数组函数调用标量函数:

function myFunctionArr(coords1, coords2) {
    const results = [];
    for (let i = 0; i < coords1.length; i++) {
        results[i] = myFunctionScalar(coords1[i], coords2[i]);
    }
    return results;
}
function myFunctionScalar(coord1, coord2) {
    const myVar1 = coord1 * coord2;
    const myVar2 = myVar1 / coord2 + myVar1;
    return coord1 * (coord2 / myVar2);
}

当然你也可以把它变成一个重载函数,比如

function myFunction(coord1, coord2) {
    if (Array.isArray(coord1)) { // args are arrays
        return myFunctionArr(coord1, coord2);
    } else { // args are scalar
        return myFunctionScalar(coord1, coord2);
    }
}

你甚至可以在一个辅助函数中抽象出一个函数在多个数组元素上的元素应用(也由许多具有功能意识的库提供):

return zipWith(myFunctionScalar, coords1, coords2)

推荐阅读