diff --git a/Cargo.lock b/Cargo.lock index e26d138f..b310aa4c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -81,7 +81,7 @@ dependencies = [ [[package]] name = "calcit_runner" -version = "0.3.27" +version = "0.3.28" dependencies = [ "chrono", "cirru_edn", diff --git a/Cargo.toml b/Cargo.toml index f0cf3b79..581b2388 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "calcit_runner" -version = "0.3.27" +version = "0.3.28" authors = ["jiyinyiyong "] edition = "2018" license = "MIT" diff --git a/lib/calcit-data.ts b/lib/calcit-data.ts index 9f3bed97..79c2db2e 100644 --- a/lib/calcit-data.ts +++ b/lib/calcit-data.ts @@ -440,6 +440,7 @@ export let getStringName = (x: CrDataValue): string => { throw new Error("Cannot get string as name"); }; +/** returns -1 when not found */ export function findInFields(xs: Array, y: string): number { let lower = 0; let upper = xs.length - 1; diff --git a/lib/calcit.procs.ts b/lib/calcit.procs.ts index e71e97c5..c1164604 100644 --- a/lib/calcit.procs.ts +++ b/lib/calcit.procs.ts @@ -28,7 +28,7 @@ export * from "./calcit-data"; export * from "./record-procs"; export * from "./custom-formatter"; -export const calcit_version = "0.3.27"; +export const calcit_version = "0.3.28"; let inNodeJs = typeof process !== "undefined" && process?.release?.name === "node"; diff --git a/lib/record-procs.ts b/lib/record-procs.ts index bdb5bf8d..3d607933 100644 --- a/lib/record-procs.ts +++ b/lib/record-procs.ts @@ -15,6 +15,7 @@ import { cloneSet, getStringName, CrDataRecord, + findInFields, } from "./calcit-data"; export let new_record = (name: CrDataValue, ...fields: Array): CrDataValue => { @@ -39,7 +40,7 @@ export let fieldsEqual = (xs: Array, ys: Array): boolean => { if (xs.length !== ys.length) { return false; } - for (let idx in xs) { + for (let idx = 0; idx < xs.length; idx++) { if (xs[idx] !== ys[idx]) { return false; } @@ -52,18 +53,31 @@ export let _AND__PCT__MAP_ = (proto: CrDataValue, ...xs: Array): Cr if (xs.length % 2 !== 0) { throw new Error("Expected even number of key/value"); } - let pairs: Array<[string, CrDataValue]> = []; - for (let i = 0; i < xs.length >> 1; i++) { - let idx = i << 1; - pairs.push([getStringName(xs[idx]), xs[idx + 1]]); + if (xs.length !== proto.fields.length * 2) { + throw new Error("fields size does not match"); } - // mutable sort for perf - pairs.sort(fieldPairOrder); - let fields = pairs.map((ys) => ys[0]); - if (!fieldsEqual(fields, proto.fields)) { - throw new Error("Fields does not match prototype"); + + let values = new Array(proto.fields.length); + + for (let i = 0; i < proto.fields.length; i++) { + let idx = -1; + let k = proto.fields[i]; + for (let j = 0; j < proto.fields.length; j++) { + if (k === getStringName(xs[j * 2])) { + idx = j; + break; + } + } + + if (idx < 0) { + throw new Error("invalid field name for this record"); + } + if (values[i] != null) { + throw new Error("record field already has value, probably duplicated key"); + } + values[i] = xs[idx * 2 + 1]; } - let values = pairs.map((ys) => ys[1]); + return new CrDataRecord(proto.name, proto.fields, values); } else { throw new Error("Expected prototype to be a record"); diff --git a/package.json b/package.json index a74deaa7..4386e38c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@calcit/procs", - "version": "0.3.27", + "version": "0.3.28", "main": "./lib/calcit.procs.js", "devDependencies": { "@types/node": "^15.0.1",