为什么将数字作为字符串传递到数组中会导致错误的结果?

时间:2018-11-19 15:36:39

标签: javascript

我构建了一个函数,该函数使您可以通过数组,并且可以成功返回第二高和第二低的数字。但是,我是错误处理的新手,也不知道为什么会失败:

getNos([5,"5",8]);

在传递getNos([5,5,8])时它可以正常工作;或传递类似getNos(["5",8]);的数组。

有人可以解释这里发生了什么以及如何解决吗?感谢您的帮助-功能代码如下:

function getNos(arr){

if (!Array.isArray(arr) || arr.length == 0 || arr.length == 1 || (arr.every(c => !isNaN(c)) == false)) {
    throw 'Invalid Input';
} else {

    var result;
    var uniqueVals = Array.from(new Set(arr));
    var highest = highestVal(arr);
    var lowest = lowestVal(arr);

    if (uniqueVals.length == 1) {
        result = arr[0] + " " + arr[0];
    } else if (arr.length == 2 || uniqueVals.length == 2) {
        result = highest + " " + lowest;
    } else {
        arr = arr.filter(item => ((item !== highest) && (item !== lowest)));
        var secondHighest = highestVal(arr);
        var secondLowest = lowestVal(arr);

        if (arr.length == 1) {
            arr = arr.slice(arr.indexOf(secondHighest));
            result = highestVal(arr);
        } else {
            result = secondLowest + " " + secondHighest;
        }
    }
    return result;
}

function highestVal(a) { return a.reduce((a, b) => a > b ? a : b ) };
function lowestVal(a) { return a.reduce((a, b) => a < b ? a : b ) };
}

3 个答案:

答案 0 :(得分:3)

请仔细遵循逻辑var uniqueVals = Array.from(new Set(arr))。当您拥有[5,"5",8][5,5,8]["5", 8]之类的数组时,此行返回什么?

Set存储type的唯一值。 "5"的类型为string,而5的类型为numberhighestVallowestVal函数可以比较"5"8,没问题,但是由于数组可以包含stringnumber也可以是5或8,然后您会得到有趣的值。

要解决此问题,在将arr传递到Set之前,您需要将所有值转换为单一类型,最好是number

let numberArr = arr.map(el=>+el)是做到这一点的一种方法,但是您可能想要比这更好的数据验证。

答案 1 :(得分:1)

简单的解决方法是在创建集合之前将值映射为数字,以避免与集合中的字符串和数字具有相同的数值

更改

var uniqueVals = Array.from(new Set(arr));

收件人

var uniqueVals = Array.from(new Set(arr.map(Number)));

答案 2 :(得分:1)

该函数在抛出错误的意义上不会失败。对于这些类型的问题,请添加“预期结果”示例。

在JavaScript中比较字符串和数字时,您依靠隐式强制执行比较。在这种情况下,它不会抛出错误并且不会破坏任何内容,因为JavaScript会将您的字符串转换为数字并进行比较(除非它也严格检查等式===),这很好。

结果应该基于传入的内容吗?或者仅在输入过滤了数字之后。还是输入可以转换为有效数字?

在过滤有效数字的情况下。过滤输入内容,如下所示...

  arr = arr.filter(data => typeof data === 'number')

在将值转换为数字并删除无法转换的值的情况下...

  arr = arr.reduce(((acc, el) => {
                       const num = Number(el);
                       if (!Number.isNaN(num)) acc.push(num);
                       return acc;
                     }), []);