范围方法 getValues() 返回和 setValues() 接受什么?

The*_*ter 1 arrays multidimensional-array google-sheets google-apps-script

我想从我的工作表中获取一个范围。按照最佳实践中的建议,我试图获取一个数组并对其进行操作,但我很困惑:

const ss = Spreadsheet.getActive(),
  sh = ss.getSheetByName("Sheet1"),
  rg = sh.getRange("A1:C1"),//has 1,2,3
  values = rg.getValues();
console.log(values);
Run Code Online (Sandbox Code Playgroud)

日志显示

[[1,2,3]]
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我得到了所有三个元素。但是,当我记录数组(array.length)的长度时,它只是 1(而不是 3)。当我使用.indexOfor测试元素是否存在时.includes,它显示 -1 或false

const ss = Spreadsheet.getActive(),
  sh = ss.getSheetByName("Sheet1"),
  rg = sh.getRange("A1:C1"),//has 1,2,3
  values = rg.getValues();
console.log(values);
Run Code Online (Sandbox Code Playgroud)

为什么?

我有同样的问题setValues()

rg.setValues([1,2,3]);//throws error
Run Code Online (Sandbox Code Playgroud)

错误是

“参数 (number[]) 与 SpreadsheetApp.Range.setValues 的方法签名不匹配。”

我的具体问题是:究竟getValues() 返回什么?它是一种特殊的数组吗?

The*_*ter 7

文档摘录:

来自官方文档getValues()返回

二维值数组,

总是返回一个2个值的二维阵列。

一维数组是

[1,2,3]
Run Code Online (Sandbox Code Playgroud)

二维数组是

[[1,2,3]]
//or
[[1], [2], [3]]
Run Code Online (Sandbox Code Playgroud)

数组中有/有数组。

按行索引,然后按列索引。

它首先按行索引:即,外部数组将行作为内部数组。然后每个内部数组都有列元素。考虑以下简单的电子表格:

一种 C
1> 1 2 3
2> 2 3 4
3> 3 4 5

A1:A3包含 3 行,每行包含 1 个列元素。这表示为[[1],[2],[3]]。同样,以下范围代表以下数组:

A1
符号


数组
结构
数组
.length
数组[0]
.length
A1:A3 3 1 [[1],[2],[3]] 3 1
A1:C1 1 3 [[1,2,3]] 1 3
A1:B2 2 2 [[1,2],[2,3]] 2 2
B1:C3 3 2 [[2,3],[3,4],[4,5]] 3 2
A2:C3 2 3 [[2,3,4],[3,4,5]] 2 3

注意二维如何提供方向。请参阅下面的实时可视化:

根据单元格的值,值可以是数字、布尔值、日期或字符串类型。

在上面的示例中,我们将电子表格数字类型元素转换为 JavaScript 数字类型。您可以使用 来检查电子表格类型=TYPE()。对应的 JavaScript 类型参考在这里

空单元格由数组中的空字符串表示。

检查使用

console.log(values[0][0]==="")//logs true if A1 is empty    
Run Code Online (Sandbox Code Playgroud)

请记住,虽然范围索引从 1, 1 开始,但 JavaScript 数组从 [0][0] 开始索引。

给定二维数组结构,要访问一个值,需要两个格式索引array[row][column]。在上表中,如果A2:C3检索到,要访问C3,使用values[1][2][1]是范围 A2:C3 中的第二行。请注意,范围本身从第二行开始。因此,第二行给定的范围是行3 [2]的第三列C

笔记:

  • 警告:

无论范围的高度或宽度如何(即使它只是 1),从范围中检索的值始终是 二维的。将代表getRange("A1").getValues()[[1]]

  • setValues()将接受与rangeto 设置对应的相同数组结构。如果尝试使用一维数组,则错误

参数 (number[]/string[]) 与 SpreadsheetApp.Range.setValues 的方法签名不匹配。

被抛出。

  • 如果数组不完全对应于设置的范围,即,如果内部数组的每个长度不对应于范围中的列数或外部数组的长度不对应于范围中的行数正在设置,抛出类似如下的错误:

数据中的列数与范围中的列数不匹配。数据有 5,但范围有 6。

  • 上述错误的相关答案:

  • indexOf / includes使用严格的类型检查。当您将基元与数组对象进行比较时,它们将不起作用。您可以使用Array.flat将二维数组展平为一维数组。或者,使用普通的旧 for 循环来检查某些内容。

    /*<ignore>*/console.config({maximize:true,timeStamps:false,autoScroll:false});/*</ignore>*/
    const test = {
      'A1:A3': [[1], [2], [3]],
      'A1:C1': [[1, 2, 3]],
      'A1:B2': [
        [1, 2],
        [2, 3],
      ],
      'B1:C3': [
        [2, 3],
        [3, 4],
        [4, 5],
      ],
      'A2:C3': [
        [2, 3, 4],
        [3, 4, 5],
      ],
    };
    
    Object.entries(test).forEach(([key, value]) => {
      console.log(`The range is ${key}`);
      console.table(value);
      console.info(`The above table's JavaScript array notation is ${JSON.stringify(value)}`)
      console.log(`=================================`);
    });
    Run Code Online (Sandbox Code Playgroud)

参考: