Javascript 为什么我会从谷歌脚本中的indexOf操作中得到不一致的结果,而这些结果似乎是完全相同的输入?

Javascript 为什么我会从谷歌脚本中的indexOf操作中得到不一致的结果,而这些结果似乎是完全相同的输入?,javascript,arrays,google-apps-script,google-sheets,indexof,Javascript,Arrays,Google Apps Script,Google Sheets,Indexof,我曾试图找到一种在谷歌脚本中搜索数组的方法,但我一直找不到任何有效的方法。我的最终任务是在Google工作表中的多个数组上进行vlookup操作,在这些数组上执行函数,然后将它们放入另一个数组中进行粘贴分析。我有大约2500个循环,我需要这样做,所以我尽量避免读/写。这是我的主要障碍的一个极其简单的版本 当我在数组中查找数字的索引时,除非我查找该数组的子集,否则我无法得到除-1之外的任何内容。当我寻找不同阵列的精确副本或硬编码时,结果并不一致。提前感谢您的帮助和耐心 这是指向my的链接,下面是一

我曾试图找到一种在谷歌脚本中搜索数组的方法,但我一直找不到任何有效的方法。我的最终任务是在Google工作表中的多个数组上进行vlookup操作,在这些数组上执行函数,然后将它们放入另一个数组中进行粘贴分析。我有大约2500个循环,我需要这样做,所以我尽量避免读/写。这是我的主要障碍的一个极其简单的版本

当我在数组中查找数字的索引时,除非我查找该数组的子集,否则我无法得到除-1之外的任何内容。当我寻找不同阵列的精确副本或硬编码时,结果并不一致。提前感谢您的帮助和耐心

这是指向my的链接,下面是一张图片供快速参考:

这是我试图使用的代码,表明我得到了不同的索引,我认为应该是相同的结果:

    function indexOfTest() {

  //Set sheets
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var dataSheet = ss.getSheetByName("Data");

  //Get ranges
  var dataRange = dataSheet.getRange("A1:B7").getValues(); //data set of the locations I want to search eventually
  var findRange = dataSheet.getRange("E3:E4").getValues(); //values I want to find the row of in the data set (would change in the spreadsheet based on the user's inputs)
  var locationRange = dataSheet.getRange(1,1,dataSheet.getLastRow()).getValues(); //smaller range of the locations I want to locate (1st column) 

  //test showing that indexOf works when I search for a subset of the array within the array
  var findTest1 = locationRange[2]; //set variable to a subset of the array I will search
  var searchResult1 = locationRange.indexOf(findTest1); //finding the index of the subset of the array within the array

  //test showing that indexOf does NOT work when I search for the exact same value in the same array  
  var findTest2 = findRange[0]; //set variable to the the user-entered cell on the sheet which is exactly the same as the subset of the array from the first test
  var searchResult2 = locationRange.indexOf(findTest2); //this comes back as -1 for some reason 

  //test showing that I can't even find it when I hard code it to exactly the same as somethng in the array that I was able to find earlier  
  var findTest3 = [13]; //hardcoded variable to exactly the same as the subset of the array from the first test
  var searchResult3 = locationRange.indexOf(findTest3); //this comes back as -1 for some reason 

  var x = 1 // this is where I have the debug spot (x = 1 is meaningless but wanted the debugger to stop here) 
  // why does the indexOf function work for the first test but not the other two?!?!?!?
  // any help would be greatly appreciated! thanks!

}
当我查看调试器时,我不明白为什么我在两个测试中得到-1,但它在一个测试中有效。。。他们在寻找完全一样的东西

非常感谢你

这个答案怎么样

getValues()检索的值是二维数组。

这对于你的处境来说是非常重要的一点

1.准备工作 作为准备,它确认
dataRange
findRange
locationRange
findTest1
findTest2
findTest3
的值

当检索到
dataRange
findRange
locationRange
时,如下所示

dataRange = [["Location #","State"],[11,"AK"],[13,"NE"],[17,"FL"],[24,"IL"],[47,"IL"],[69,"NV"]]
findRange = [[13],["State"]]
locationRange = [["Location #"],[11],[13],[17],[24],[47],[69]]
findTest1
findTest2
findTest3
[13]

2.实验 这里,它考虑使用
findTest1
findTest2
findTest3
进行搜索的大约3种模式

模式1 在这种情况下,从
[13]
中搜索
[[“位置”]、[11]、[13]、[17]、[24]、[47]、[69]
,即
位置范围。但是
findTest1
locationRange
中。这很有效。我认为是因为
indexOf()
可能使用同一数组中的元素引用同一数组中的指针。作为另一个示例,请参见以下示例脚本

var ar = [[1, 2, 3], [4, 5, 6], [4, 5, 6], [7, 8, 9]];
var r1 = ar.indexOf([4, 5, 6]); // -1
var r2 = ar.indexOf(ar[2]); // 2
在这个脚本中,
indexOf()
可以使用相同二维数组中的元素。在
Array.prototype.indexOf()
中,当用于搜索的值是数组时,指针可能会被引用。这个结果对我来说是一个新发现

模式2 在这种情况下,从
[13]
中搜索
[[“位置”]、[11]、[13]、[17]、[24]、[47]、[69]
,即
位置范围。但是
findTest2
不在
locationRange
中。这样,
indexOf()
尝试作为值进行搜索。但由于二维数组,它不起作用。如果使用
[13]
搜索指针,也不会找到它,因为
[13]
不是
位置范围中的元素

模式3 在本例中,情况与模式2相同

3.修改脚本 如果您想从
locationRange
搜索
13
,我认为在您的情况下,可以使用以下修改。在这个修改后的脚本中,
searchResult1
searchResult2
searchResult3
2

function indexOfTest2() {
  //Set sheets
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var dataSheet = ss.getSheetByName("Data");

  //Get ranges
  var dataRange = dataSheet.getRange("A1:B7").getValues(); //data set of the locations I want to search eventually
  var findRange = dataSheet.getRange("E3:E4").getValues(); //values I want to find the row of in the data set (would change in the spreadsheet based on the user's inputs)
  var locationRange = dataSheet.getRange(1,1,dataSheet.getLastRow()).getValues(); //smaller range of the locations I want to locate (1st column) 

  // Below script was modified.
  locationRange = Array.prototype.concat.apply([], locationRange);
  var findTest1 = locationRange[2];
  var searchResult1 = locationRange.indexOf(findTest1);
  var findTest2 = findRange[0][0];
  var searchResult2 = locationRange.indexOf(findTest2);
  var findTest3 = [13][0];
  var searchResult3 = locationRange.indexOf(findTest3);
}
注:
  • Array.prototype.concat.apply([],locationRange)
    [“Location”、“State”]、[11,“AK”]、[13,“NE”]、[17,“FL”]、[24,“IL”]、[47,“IL”]、[69,“NV”]]的二维数组转换为
    [“Location”、[11,13,17,24,47,47,69]
    的一维数组
  • findTest1
    中,使用
    locationRange[2]
    ,因为
    locationRange
    是一维数组
  • findTest2
    中,使用
    var findTest2=findRange[0][0]
    ,因为
    findRange
    是二维数组
  • findTest3
    ,使用
    var findTest3=[13][0]
    ,因为它从
    [13]
    检索
    13
4.参考资料:
如果这不是您想要的,我很抱歉。

根据JavaScript规范,使用:

indexOf()
使用严格相等(与
==
或三重相等运算符使用的方法相同)将
searchElement
数组的元素进行比较

在同一类型的
对象
s中,严格相等意味着对象A必须与
A===B
的对象B完全相同的对象引用才是
。具有相同值的两个对象并不意味着它们具有相同的对象引用:

var A = ['A', 'B', 'C'];
var B = ['A', 'B', 'C'];
Logger.log(A === B) // false
B = A;
Logger.log(A === B) // true
B = A.slice(0);
Logger.log(A === B) // false
Logger.log(A.map(function (ai, i) { return ai === B[i]; })); // true, true, true

在最近的JS版本中,您可以使用它来执行基于值的比较。然而,应用程序脚本只是JS1.6(带有一些铃铛+口哨),但是
包含的
不是其中之一。

我认为将其转换为1D数组将使我达到我需要的目的。非常感谢你的帮助,祝你度过愉快的一天@欢迎光临。谢谢你让我知道。如果您的问题已解决,请按“接受”按钮。与您有相同问题的其他人也可以将您的问题作为可以解决的问题。如果你找不到按钮,尽管告诉我@谢谢你的回复,谢谢!不幸的是,我一直在使用应用程序脚本,所以我将转换为另一个答案中提到的1D数组,但知道这一点很好。祝你过得愉快,再次感谢你!
var findTest3 = [13];
var searchResult3 = locationRange.indexOf(findTest3);
function indexOfTest2() {
  //Set sheets
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var dataSheet = ss.getSheetByName("Data");

  //Get ranges
  var dataRange = dataSheet.getRange("A1:B7").getValues(); //data set of the locations I want to search eventually
  var findRange = dataSheet.getRange("E3:E4").getValues(); //values I want to find the row of in the data set (would change in the spreadsheet based on the user's inputs)
  var locationRange = dataSheet.getRange(1,1,dataSheet.getLastRow()).getValues(); //smaller range of the locations I want to locate (1st column) 

  // Below script was modified.
  locationRange = Array.prototype.concat.apply([], locationRange);
  var findTest1 = locationRange[2];
  var searchResult1 = locationRange.indexOf(findTest1);
  var findTest2 = findRange[0][0];
  var searchResult2 = locationRange.indexOf(findTest2);
  var findTest3 = [13][0];
  var searchResult3 = locationRange.indexOf(findTest3);
}
var A = ['A', 'B', 'C'];
var B = ['A', 'B', 'C'];
Logger.log(A === B) // false
B = A;
Logger.log(A === B) // true
B = A.slice(0);
Logger.log(A === B) // false
Logger.log(A.map(function (ai, i) { return ai === B[i]; })); // true, true, true