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 机制有关,这就是为什么我费心在这里更新它——也许有人会知道是什么导致了这种行为。
回顾一下——我想根据给定变量的内容是否匹配数组中的任一 值来调整操作。我试过同时使用 includes
和 indexOf
,但是这两种方法都失败了。问题归结为函数没有进行 exact 匹配。比如我有一个5个数字的数组比如8, 9, 12, 13, 14
,我想测试数组中是否存在4
,那么精确匹配应该是return FALSE
.但是,indexOf
和 contains
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
我想构建一个 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 机制有关,这就是为什么我费心在这里更新它——也许有人会知道是什么导致了这种行为。
回顾一下——我想根据给定变量的内容是否匹配数组中的任一 值来调整操作。我试过同时使用 includes
和 indexOf
,但是这两种方法都失败了。问题归结为函数没有进行 exact 匹配。比如我有一个5个数字的数组比如8, 9, 12, 13, 14
,我想测试数组中是否存在4
,那么精确匹配应该是return FALSE
.但是,indexOf
和 contains
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