indexOf / includes 不做精确匹配和 return 误报

indexOf / includes don't do an exact match and return false positives

我想构建一个 if 语句,其中 if 条件基于变量是否等于 any 的相等性测试几个值。但是,我不想对测试值进行硬编码,而是传递一组先前随机子集的值。

首先,我通过从 15 个值的数组中 subsetting/sampling 5 个值得到一组随机值。基本上,我使用 this excellent solution.

function getRandomSubarray(arr, size) {
    var shuffled = arr.slice(0), i = arr.length, temp, index;
    while (i--) {
        index = Math.floor((i + 1) * Math.random());
        temp = shuffled[index];
        shuffled[index] = shuffled[i];
        shuffled[i] = temp;
    }
    return shuffled.slice(0, size);
}

var x = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
var fiveRandomMembers = getRandomSubarray(x, 5);

然后,我想通过fiveRandomMembers来测试一个变量是否等于fiveRandomMembers的数组中的任何值。然后做点什么。为此,我想使用this solution.

var L = function()
{
    var obj = {};
    for(var i=0; i<arguments.length; i++)
        obj[arguments[i]] = null;

    return obj;
};

if(foo in L(fiveRandomMembers)) {
/// do something
};

不幸的是,这对我不起作用。我必须承认,此代码的实施是在 Qualtrics 调查中进行的,因此问题 可能 与 Qualtrics 平台有细微差别,这就是它对我不起作用的原因。我是 JavaScript 的新手,如果这是一个微不足道的问题,我深表歉意。但是我相信我的代码即使在 JavaScript 中也是有问题的(也就是说,不管 Qualtrics),我想弄清楚为什么。

更新 2020-05-24

我对此进行了更深入的研究,并且有了一些见解。这看起来更像是一个质量问题而不是普通的 JS 问题。然而,潜在的问题可能仍然与某些 JS 机制有关,这就是为什么我费心在这里更新它——也许有人会知道是什么导致了这种行为。

回顾一下——我想根据给定变量的内容是否匹配数组中的任一 值来调整操作。我试过同时使用 includesindexOf,但是这两种方法都失败了。问题归结为函数没有进行 exact 匹配。比如我有一个5个数字的数组比如8, 9, 12, 13, 14,我想测试数组中是否存在4,那么精确匹配应该是return FALSE .但是,indexOfcontains return TRUE 因为 14 里面有 4。这不是精确匹配。此外,我试图调查 indexOf 对这种误报匹配的 return 的位置是什么。通常,它会 return 一个甚至大于数组总长度的位置,这毫无意义。这是我的 Qualtrics 调查的一个例子,说明了这个问题:

给出此代码的代码由两个定性问题组成:

(-) 第一张

Qualtrics.SurveyEngine.addOnReady(function()
{
    /*Place your JavaScript here to run when the page is fully displayed*/

    function getRandomSubarray(arr, size) {
    var shuffled = arr.slice(0), i = arr.length, temp, index;
    while (i--) {
        index = Math.floor((i + 1) * Math.random());
        temp = shuffled[index];
        shuffled[index] = shuffled[i];
        shuffled[i] = temp;
    }
    return shuffled.slice(0, size);
}

var x = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
var fiveRandomMembers = getRandomSubarray(x, 5);

if (Array.isArray(fiveRandomMembers)) Qualtrics.SurveyEngine.setEmbeddedData('is_array', "TRUE");


Qualtrics.SurveyEngine.setEmbeddedData('length', fiveRandomMembers.length);


Qualtrics.SurveyEngine.setEmbeddedData('five_sampled_numbers', fiveRandomMembers);

});

(-) 第二张

Qualtrics.SurveyEngine.addOnReady(function()
{
    jQuery("#"+this.questionId).find('.QuestionText:first').css("padding-bottom", "0px");


var currentLoopNum = "${lm://CurrentLoopNumber}";
    // var currentLoopNum = parseInt(currentLoopNum, 10); // tried converting to numeric but it doesn't solve the problem
var fiveSampledNumbers = "${e://Field/five_sampled_numbers}";

if (fiveSampledNumbers.includes(currentLoopNum)) {
   Qualtrics.SurveyEngine.setEmbeddedData('does_loop_number_appear', "Yes");
} else {
    Qualtrics.SurveyEngine.setEmbeddedData('does_loop_number_appear', "No");

}
    Qualtrics.SurveyEngine.setEmbeddedData('index_of', fiveSampledNumbers.indexOf(currentLoopNum));

});

这是 Qualtrics 调查的 link,演示了问题,以防对故障排除有所帮助link


但是, 在 Qualtrics 之外测试相同代码时,问题不会重现。

有人知道匹配的问题是什么吗?即使您不一定熟悉 Qualtrics...

我以前从未与 Qualtrics 合作过,但对我来说很明显

var fiveSampledNumbers = "${e://Field/five_sampled_numbers}";

将字符串值分配给 fiveSampledNumbers,而不是数组值。

事实上,如果您尝试 运行 您正在对字符串而不是数组进行的检查,您会得到上面看到的意外结果,因为您正在执行字符串操作而不是数组操作:

var fiveSampledNumbers = "6,4,10,11,15";
console.log(fiveSampledNumbers.includes(5));  // logs true (string ends with the character "5")
console.log(fiveSampledNumbers.indexOf(5));   // logs 11   (index of the character "5")

要解决这个问题,您必须用逗号分隔字符串并解析其中的每个数字:

var fiveSampledNumbers = "6,4,10,11,15";
fiveSampledNumbers = fiveSampledNumbers.split(",").map(function (n) { return parseInt(n, 10); });
console.log(fiveSampledNumbers.includes(5));  // logs false
console.log(fiveSampledNumbers.indexOf(5));   // logs -1