Skip to content

Commit

Permalink
feat!: split method and create ndParseWithLineType (replace the tag o…
Browse files Browse the repository at this point in the history
…ption)
  • Loading branch information
lpatiny committed Mar 20, 2024
1 parent c595035 commit 4c6123a
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 28 deletions.
9 changes: 0 additions & 9 deletions src/__tests__/ndParse.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,3 @@ test('real file', () => {
expect(Object.keys(parsed.variables)).toStrictEqual(keys);
});

test('breakdown', () => {
const csv = readFileSync(
join(__dirname, '../../testFiles/breakdown.csv'),
'latin1',
);
const parsed = ndParse(csv, { isTagged: true });
const keys = ['x', 'y', 'I', 'a', 'b', 'c'];
expect(Object.keys(parsed.variables)).toStrictEqual(keys);
});
14 changes: 14 additions & 0 deletions src/__tests__/ndParseWithLineType.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {readFileSync} from 'fs';
import {join} from 'path';

Check warning on line 2 in src/__tests__/ndParseWithLineType.test.ts

View workflow job for this annotation

GitHub Actions / nodejs / lint-eslint

There should be at least one empty line between import groups
import {test, expect} from 'vitest';

Check warning on line 3 in src/__tests__/ndParseWithLineType.test.ts

View workflow job for this annotation

GitHub Actions / nodejs / lint-eslint

There should be at least one empty line between import groups
import { ndParseWithLineType } from '../ndParseWithLineType';

test('breakdown', () => {
const csv = readFileSync(
join(__dirname, '../../testFiles/breakdown.csv'),
'latin1',
);
const parsed = ndParseWithLineType(csv, { isTagged: true });
const keys = ['x', 'y', 'I', 'a', 'b', 'c'];
expect(Object.keys(parsed.variables)).toStrictEqual(keys);
});
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './ndParse';
export * from './ndParseWithLineType';
export * from './appended';
export * from './types';
22 changes: 3 additions & 19 deletions src/ndParse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ export function ndParse(
): MeasurementXY<number[]> {
const {
separator = ',',
isTagged = false,
keyMap = defaultKeyMapper,
labelMap = defaultLabelMap,
} = options || {};
Expand All @@ -21,19 +20,14 @@ export function ndParse(
let tempHeader: string[] = [];
let header: OneLowerCase[] | undefined;
let labels: string[] = [];
let prevTag: string | undefined;
let tag: string | undefined;

const lines = text.split(/\r\n|\r|\n/);

for (const line of lines){
const fields = line.split(separator);
if (isTagged) {
prevTag = tag;
tag = fields.shift();
}

const isNumeric =
line && (isTagged ? tag === 'DataValue' : !isNaN(Number(fields[0])));
line && !isNaN(Number(fields[0]));
// Checks if the header is set
if (!header) {
// Classifies if it's a header
Expand All @@ -51,17 +45,7 @@ const lines = text.split(/\r\n|\r|\n/);
// Add meta-values
if (tempHeader) {
const [key, ...values] = tempHeader.filter((t) => t);
if (
prevTag &&
[
'SetupTitle',
'PrimitiveTest',
'Dimension1',
'Dimension2',
].includes(prevTag)
) {
meta[prevTag] = [key, ...values].join(separator);
} else if (key) {
if (key) {
meta[key] = values.join(separator);
}
}
Expand Down
83 changes: 83 additions & 0 deletions src/ndParseWithLineType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import type { MeasurementXY, OneLowerCase, TextData } from 'cheminfo-types';
import { ensureString } from 'ensure-string';

import type { GeneralOptionsType } from './types';
import { defaultKeyMapper, defaultLabelMap, intToChar } from './utils';

export function ndParseWithLineType(
blob: TextData,
options?: GeneralOptionsType,
): MeasurementXY<number[]> {
const {
separator = ',',
keyMap = defaultKeyMapper,
labelMap = defaultLabelMap,
} = options || {};
const text = ensureString(blob);
const meta: MeasurementXY['meta'] = {};
const variables: Partial<MeasurementXY<number[]>['variables']> = {};

let tempHeader: string[] = [];
let header: OneLowerCase[] | undefined;
let labels: string[] = [];
let previousLineType: string | undefined;
let lineType: string | undefined;

const lines = text.split(/\r\n|\r|\n/);

for (const line of lines){
const fields = line.split(separator);
previousLineType = lineType;
lineType = fields.shift();
const isNumeric =
line &&lineType === 'DataValue';
// Checks if the header is set
if (!header) {
// Classifies if it's a header
if (isNumeric) {
// Fix the header
header = keyMap(tempHeader);
labels = labelMap(tempHeader);
for (let index = 0; index < fields.length; index++) {
const label = labels[index] || intToChar(index);
const value = Number(fields[index]);
const key = header[index];
if (!isNaN(value)) variables[key] = { data: [value], label };
}
} else {
// Add meta-values
if (tempHeader) {
const [key, ...values] = tempHeader.filter((t) => t);
if (
previousLineType &&
[
'SetupTitle',
'PrimitiveTest',
'Dimension1',
'Dimension2',
].includes(previousLineType)
) {
meta[previousLineType] = [key, ...values].join(separator);
} else if (key) {
meta[key] = values.join(separator);
}
}
tempHeader = fields.map((t) => t.trim());
}
}

// Deals with numerical values
else if (isNumeric) {
for (let index = 0; index < fields.length; index++) {
const key = header ? header[index] : intToChar(index);
const value = Number(fields[index]);
if (!isNaN(value)) variables[key]?.data.push(value);
}
}
}

const { x, y, ...unorderedData } = variables;
if (!x || !y) throw new Error('x and y variables are necessary');

return { meta, variables: { x, y, ...unorderedData } };
}

0 comments on commit 4c6123a

Please sign in to comment.