【问题标题】:What does the range method getValues() return and setValues() accept?range 方法 getValues() 返回和 setValues() 接受什么?
【发布时间】:2020-12-22 12:18:49
【问题描述】:

我想从我的工作表中获取一个范围。正如Best practices 中所建议的那样,我正在尝试获取一个数组并对其进行操作,但我很困惑:

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

日志显示

[[1,2,3]]

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

const values = /*same as logged above*/[[1,2,3]];
console.log(values.indexOf(2));//got -1 expected 1
console.log(values.includes(1));//got false expected true

为什么?

setValues() 也有同样的问题。

rg.setValues([1,2,3]);//throws error

错误是

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

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

【问题讨论】:

  • 欢迎用不同的方法来解释这个概念。关于这个概念的问题已被反复提出。感谢您对此问题的新答案。

标签: arrays google-apps-script multidimensional-array google-sheets


【解决方案1】:

文档摘录:

来自official documentationgetValues() 返回

二维数组,

总是返回一个二维值数组。

一维数组是

[1,2,3]

二维数组是

[[1,2,3]]
//or
[[1], [2], [3]]

数组中有/是数组。

按行索引,然后按列。

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

A B C
1> 1 2 3
2> 2 3 4
3> 3 4 5

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

A1
Notation
Number
of Rows
Number
of columns
Array
Structure
array
.length
array[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

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

/*<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(`=================================`);
});
&lt;!-- https://meta.stackoverflow.com/a/375985/ --&gt;    &lt;script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"&gt;&lt;/script&gt;

值可能是数字、布尔值、日期或字符串类型,具体取决于单元格的值。

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

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

检查使用

console.log(values[0][0]==="")//logs true if A1 is empty    

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

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

注意事项:

  • 警告:

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

  • setValues() 将接受与 range 对应的相同数组结构进行设置。如果尝试一维数组,则会出现错误

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

被抛出。

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

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

  • 上述错误的相关解答:

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

    const values = [[1,2,3]].flat();//flattened
    console.log(values.indexOf(2));//expected 1
    console.log(values.includes(1));//expected true

参考资料:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多