Sheet 二维数组表类
Sheet 是 Alia 的内置二维数组表类,用于处理多个数组之间的映射关系,是类似 Excel 表格的数据结构。支持高效的表格操作、数据查找和表连接功能。
创建 Sheet
使用表头和数据创建
const headers = ['id', 'name', 'age', 'city']
const data = [
[1, 'Alice', 25, 'Beijing'],
[2, 'Bob', 30, 'Shanghai'],
[3, 'Charlie', 35, 'Guangzhou']
]
const sheet = new Sheet [headers, data]
创建空 Sheet
const emptySheet = new Sheet
从 CSV 文件导入
Alia 支持通过 import 语句直接从 CSV 文件导入数据,自动转换为 Sheet 类型。
~ data.csv 文件内容:
~ name,age,city,score
~ Alice,30,Beijing,95
~ Bob,25,Shanghai,88
~ Charlie,35,Guangzhou,92
import 'data.csv' as sheet
print sheet.getCell at row 0 column 'name' ~ 输出 'Alice'
print sheet.getCell at row 1 column 'age' ~ 输出 30
print sheet.getCell at row 2 column 'score' ~ 输出 92
特性:
- CSV 文件第一行自动识别为表头
- 支持数字、布尔值(true/false,不区分大小写)和字符串的类型识别
- 空单元格转换为
null - 支持引号包裹的字段(包含逗号的字段)
- 自动处理 Windows 和 Unix 换行符
实例属性
headers
返回表头数组(只读)。
const sheet = new Sheet [['id', 'name', 'age'], [[1, 'Alice', 25]]]
print sheet.headers ~ 输出: ['id', 'name', 'age']
data
返回数据二维数组(只读)。
const sheet = new Sheet [['id', 'name'], [[1, 'Alice'], [2, 'Bob']]]
print sheet.data ~ 输出: [[1, 'Alice'], [2, 'Bob']]
rowMap
返回行索引映射表(只读)。索引键以 __index_ 为前缀。
const sheet = new Sheet [['id', 'name'], [[1, 'Alice'], [2, 'Bob']]]
sheet.buildIndex 'id'
print sheet.rowMap ~ 输出: [object Map]
实例方法
getRow
获取指定索引的行。签名为 sheet.getRow index,接收行索引并返回该行的数组副本。
const sheet = new Sheet [['id', 'name', 'age'], [[1, 'Alice', 25], [2, 'Bob', 30]]]
print sheet.getRow 0 ~ 输出: [1, 'Alice', 25]
print sheet.getRow 1 ~ 输出: [2, 'Bob', 30]
getColumn
获取指定列名的所有数据。签名为 sheet.getColumn key,接收列名并返回该列的一维数组。
const sheet = new Sheet [['id', 'name', 'city'], [[1, 'Alice', 'Beijing'], [2, 'Bob', 'Shanghai']]]
print sheet.getColumn 'name' ~ 输出: ['Alice', 'Bob']
print sheet.getColumn 'city' ~ 输出: ['Beijing', 'Shanghai']
getCell
获取指定单元格的值。签名为 sheet.getCell at row R column C,返回单元格的值。
const sheet = new Sheet [['id', 'name', 'age'], [[1, 'Alice', 25], [2, 'Bob', 30]]]
print sheet.getCell at row 0 column 'name' ~ 输出: 'Alice'
print sheet.getCell at row 1 column 'age' ~ 输出: 30
setCell
设置指定单元格的值。签名为 sheet.setCell at row R column C to V,返回 Sheet 本身以支持链式调用。
const sheet = new Sheet [['id', 'name', 'city'], [[1, 'Alice', 'Beijing'], [2, 'Bob', 'Shanghai']]]
sheet.setCell at row 1 column 'city' to 'Guangzhou'
print sheet.getCell at row 1 column 'city' ~ 输出: 'Guangzhou'
appendRow
追加一行数据。签名为 sheet.appendRow row,接收行数组并返回 Sheet 本身以支持链式调用。数组字面量实参采用 call 形式传 入。
const sheet = new Sheet [['id', 'name'], [[1, 'Alice'], [2, 'Bob']]]
call sheet.appendRow [[3, 'Charlie']]
print sheet.getRow 2 ~ 输出: [3, 'Charlie']
lookup
垂直查找(sheet.lookup V returning R in M)。在 matchCol 中查找等于 value 的行,返回该行 returnCol 的值。类似 Excel 的 VLOOKUP 函数。未命中时返回 null。
const sheet = new Sheet [['id', 'name', 'city'], [[1, 'Alice', 'Beijing'], [2, 'Bob', 'Shanghai']]]
~ 根据 ID 查找城市
const city = sheet.lookup 2 returning 'city' in 'id'
print city ~ 输出: 'Shanghai'
~ 查找不存在的值返回 null
const notFound = sheet.lookup 99 returning 'city' in 'id'
print notFound ~ 输出: null
join
表连接(users.join depts on L and R as Y)。将另一个 Sheet 根据左右列名进行连接,合并数据。as 后连接类型缺省时为内连接。
参数:
otherSheet: 另一个 Sheet 对象leftCol(on后): 当前 Sheet 用于连接的列名rightCol(and后): 另一个 Sheet 用于连接的列名joinType(as后): 连接类型,可选值:'inner'(默认)、'left'
~ 创建用户表
const users = new Sheet [['id', 'name', 'dept_id'], [[1, 'Alice', 101], [2, 'Bob', 102], [3, 'Charlie', 101]]]
~ 创建部门表
const depts = new Sheet [['dept_id', 'dept_name'], [[101, 'Engineering'], [102, 'Marketing'], [103, 'Sales']]]
~ 内连接
const innerJoined = users.join depts on 'dept_id' and 'dept_id' as 'inner'
print innerJoined.headers ~ 输出: ['id', 'name', 'dept_id', 'dept_name']
~ 左连接
const leftJoined = users.join depts on 'dept_id' and 'dept_id' as 'left'
groupBy
分组映射。签名为 sheet.groupBy key with fn,按某列分组,并对每组数据执行聚合函数。聚合函数为 Alias 对象,接收每组的行数组作为参数。
参数:
groupCol: 用于分组的列名aggFunc: 聚合函数,为 Alias 对象,接收 每组的行数组作为参数
const sales = new Sheet [['product', 'region', 'amount'], [
['A', 'North', 100],
['A', 'South', 150],
['B', 'North', 80],
['B', 'South', 120],
['A', 'North', 50]
]]
~ 按产品分组,计算总销售额
const sumFunc = alias <Array rows> -> {
let sum = 0
each row in rows {
sum = sum + row[2]
}
sum
}
const totalByProduct = sales.groupBy 'product' with sumFunc
print totalByProduct ~ 输出 Sheet 表格:headers 为 ['product', 'result'],分组结果 data 为 [['A', 300], ['B', 200]]
buildIndex
建立索引。签名为 sheet.buildIndex key,为指定列建立哈希映射,加速后续的 lookup 和 join 操作。返回 Sheet 本身以支持链式调用。
const sheet = new Sheet [['id', 'name', 'city'], [
[1, 'Alice', 'Beijing'],
[2, 'Bob', 'Shanghai'],
[3, 'Charlie', 'Guangzhou']
]]
~ 为 id 列建立索引
sheet.buildIndex 'id'
~ 后续的 lookup 操作会使用索引加速
const city = sheet.lookup 2 returning 'city' in 'id'
print city ~ 输出: 'Shanghai'
findIndexByValue
按值查找行索引。签名为 sheet.findIndexByValue val in column col,返回首个匹配行的索引,未命中时返回 -1。
const sheet = new Sheet [['id', 'name'], [[1, 'Alice'], [2, 'Bob']]]
print sheet.findIndexByValue 2 in column 'id' ~ 输出: 1
print sheet.findIndexByValue 99 in column 'id' ~ 输出: -1
toArray
导出纯数组(包含表头)。无参数,以 call 形式调用,返回一个二维数组,第一行为表头,后续行为数据行。
const sheet = new Sheet [['id', 'name'], [[1, 'Alice'], [2, 'Bob']]]
const arr = call sheet.toArray
print arr ~ 输出: [['id', 'name'], [1, 'Alice'], [2, 'Bob']]
toObject
导出对象。无参数,以 call 形式调用,返回以行索引为键、行对象为值的对象。
const sheet = new Sheet [['id', 'name'], [[1, 'Alice'], [2, 'Bob']]]
const obj = call sheet.toObject
print obj ~ 输出: *[0: *[id: 1, name: 'Alice'], 1: *[id: 2, name: 'Bob']]
clone
深拷贝当前 Sheet。无参数,以 call 形式调用,返回一个新的 Sheet 对象,包含相同的数据但不共享引用。
const original = new Sheet [['id', 'name'], [[1, 'Alice'], [2, 'Bob']]]
const copy = call original.clone
~ 修改副本不影响原对象
copy.setCell at row 0 column 'name' to 'Alicia'
print original.getCell at row 0 column 'name' ~ 输出: 'Alice'
print copy.getCell at row 0 column 'name' ~ 输出: 'Alicia'
toString
返回 Sheet 的字符串表示。无参数,以 call 形式调用。
const sheet = new Sheet [['id', 'name'], [[1, 'Alice'], [2, 'Bob']]]
print call sheet.toString
~ 输出:
~ Sheet:
~ id name
~ 1 Alice
~ 2 Bob
valueOf
返回 Sheet 的内部值对象,包含 headers 和 data。无参数,以 call 形式调用。
const sheet = new Sheet [['id', 'name'], [[1, 'Alice']]]
print call sheet.valueOf ~ 输出: [object Object]
使用示例
基本操作
~ 创建 Sheet
const employees = new Sheet [['id', 'name', 'department', 'salary'], [
[1, 'Alice', 'Engineering', 8000],
[2, 'Bob', 'Marketing', 6000],
[3, 'Charlie', 'Engineering', 9000],
[4, 'David', 'Sales', 5000]
]]
~ 获取所有员工姓名
const names = employees.getColumn 'name'
print ('员工姓名: ' .. (call names.toString))
~ 获取特定员工信息
const alice = employees.getRow 0
print ('Alice 的信息: ' .. (call alice.toString))
~ 更新员工薪资
employees.setCell at row 1 column 'salary' to 6500
print ('Bob 的新薪资: ' .. (employees.getCell at row 1 column 'salary'))
~ 添加新员工
call employees.appendRow [[5, 'Eve', 'Engineering', 7500]]
print ('表格行数(含表头): ' .. ((call employees.toArray).length))