From a55b4e5359c520042b411127c23320a8e7aaf0b1 Mon Sep 17 00:00:00 2001 From: Roger Qiu Date: Wed, 5 Jul 2023 16:57:43 +1000 Subject: [PATCH] feat: support `null` and `undefined` insertion and table iteration now provides row index --- src/Table.ts | 25 ++++++++++++++----------- src/utils.ts | 6 +++++- tests/Table.test.ts | 10 +++++++++- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/Table.ts b/src/Table.ts index 78cb89f..38c3dfe 100644 --- a/src/Table.ts +++ b/src/Table.ts @@ -1,4 +1,5 @@ import Counter from 'resource-counter'; +import * as utils from './utils'; class Table> { public readonly keys: Set; @@ -104,8 +105,8 @@ class Table> { return this.rows.size; } - public [Symbol.iterator](): IterableIterator> { - return this.rows.values(); + public [Symbol.iterator](): IterableIterator<[number, Readonly]> { + return this.rows.entries(); } /** @@ -201,10 +202,10 @@ class Table> { } const index = this.indexes[k]; if (index != null) { - const v_ = index.f != null ? index.f(v) : v.toString(); + const v_ = index.f != null ? index.f(v) : utils.toString(v); return [...(index.index.get(v_) ?? new Set())]; } else if (search) { - const v_ = v.toString(); + const v_ = utils.toString(v); const rIs: Array = []; for (const [rI, r] of this.rows.entries()) { if (r[k] === v_) { @@ -223,13 +224,15 @@ class Table> { const index = this.indexesDerived[kDerived]; if (index != null) { const v_ = - index.f != null ? index.f(...v) : v.map((v) => v.toString()).join(''); + index.f != null + ? index.f(...v) + : v.map((v) => utils.toString(v)).join(''); return [...(index.index.get(v_) ?? new Set())]; } else if (search) { - const v_ = v.map((v) => v.toString()).join(''); + const v_ = v.map((v) => utils.toString(v)).join(''); const rIs: Array = []; for (const [rI, r] of this.rows.entries()) { - if (k.map((k) => r[k].toString()).join('') === v_) { + if (k.map((k) => utils.toString(r[k])).join('') === v_) { rIs.push(rI); } } @@ -245,7 +248,7 @@ class Table> { for (const k in r) { const index = this.indexes[k]; if (index == null) continue; - const v = index.f != null ? index.f(r[k]) : r[k].toString(); + const v = index.f != null ? index.f(r[k]) : utils.toString(r[k]); const rIs = index.index.get(v) ?? new Set(); rIs.add(rI); index.index.set(v, rIs); @@ -264,7 +267,7 @@ class Table> { } else { v = index.deps .map((k) => r[k]) - .map((v) => v.toString()) + .map((v) => utils.toString(v)) .join(''); } const rIs = index.index.get(v) ?? new Set(); @@ -280,7 +283,7 @@ class Table> { for (const k in r) { const index = this.indexes[k]; if (index == null) continue; - const v = index.f != null ? index.f(r[k]) : r[k].toString(); + const v = index.f != null ? index.f(r[k]) : utils.toString(r[k]); const rIs = index.index.get(v)!; rIs.delete(rI); if (rIs.size === 0) { @@ -301,7 +304,7 @@ class Table> { } else { v = index.deps .map((k) => r[k]) - .map((v) => v.toString()) + .map((v) => utils.toString(v)) .join(''); } const rIs = index.index.get(v)!; diff --git a/src/utils.ts b/src/utils.ts index 29d8d8e..9541e43 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,3 +1,7 @@ +function toString(v: any) { + return v == null ? `${v}` : v.toString(); +} + /** * O(n) intersection * You can use this if you have multiple keys @@ -12,4 +16,4 @@ function intersection(...arrays: Array>): Array { return [...commonSet]; } -export { intersection }; +export { toString, intersection }; diff --git a/tests/Table.test.ts b/tests/Table.test.ts index 3cff4d0..e5a09d5 100644 --- a/tests/Table.test.ts +++ b/tests/Table.test.ts @@ -45,6 +45,14 @@ describe(Table.name, () => { const table_ = t.getTable(); expect(table_.get(1)).toBeUndefined(); }); + test('insert null and undefined values', () => { + const t = new Table<{ a: null; b: undefined }>(['a', 'b'], ['a', 'b']); + const rI = t.insertRow({ a: null, b: undefined }); + const rIs1 = t.whereRows('a', null); + expect(rIs1).toContain(rI); + const rIs2 = t.whereRows('b', undefined); + expect(rIs2).toContain(rI); + }); testProp( 'insert table rows', [ @@ -63,7 +71,7 @@ describe(Table.name, () => { const t = new Table(['a', 'b', 'c', 'd'], keysIndex); const is = rows.map((r) => t.insertRow(r)); expect(is).toEqual([...Array(rows.length).keys()]); - expect([...t]).toEqual(rows); + expect([...t]).toEqual([...rows.entries()]); expect(t.count).toBe(rows.length); }, );