diff options
| author | Priyansh <[email protected]> | 2022-01-22 21:33:06 -0500 |
|---|---|---|
| committer | Priyansh <[email protected]> | 2022-01-22 21:33:06 -0500 |
| commit | 6156ba8bc5481e6ae916bc1aebea0651c257dff8 (patch) | |
| tree | 06056f0d47229b6dca1d81e790a0880ac0d058d9 /src | |
| parent | 35a5843b68710e8bcde949d5c2e2f472dbb325e4 (diff) | |
| download | izuku.js-6156ba8bc5481e6ae916bc1aebea0651c257dff8.tar.xz izuku.js-6156ba8bc5481e6ae916bc1aebea0651c257dff8.zip | |
feat: function to load data from json and flattenJSON
Diffstat (limited to 'src')
| -rw-r--r-- | src/helpers/arrayFunctions.ts | 43 | ||||
| -rw-r--r-- | src/index.ts | 7 | ||||
| -rw-r--r-- | src/lib/data.ts | 42 | ||||
| -rw-r--r-- | src/lib/display.ts | 6 | ||||
| -rw-r--r-- | src/lib/frame.ts | 18 | ||||
| -rw-r--r-- | src/lib/info.ts | 107 |
6 files changed, 161 insertions, 62 deletions
diff --git a/src/helpers/arrayFunctions.ts b/src/helpers/arrayFunctions.ts index 234e135..e6a6c50 100644 --- a/src/helpers/arrayFunctions.ts +++ b/src/helpers/arrayFunctions.ts @@ -54,3 +54,46 @@ export function range( } return rangeArray; } + +/** + * flattenJSON - converts a nested JSON object into a simple JSON object + * @param object: the object to be flattened + * @returns the flattened object + */ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +export function flattenJSON(data: any): any { + const result: any = {}; + function recurse(cur: any, prop: string) { + if (Object(cur) !== cur) { + result[prop] = cur; + } else if (Array.isArray(cur)) { + // eslint-disable-next-line no-var + for (var i = 0, l = cur.length; i < l; i++) + recurse(cur[i], prop + '[' + i + ']'); + if (l == 0) result[prop] = []; + } else { + let isEmpty = true; + for (const p in cur) { + isEmpty = false; + recurse(cur[p], prop ? prop + '.' + p : p); + } + if (isEmpty && prop) result[prop] = {}; + } + } + recurse(data, ''); + return result; +} + +/** + * isValidJSONObject - checks if the object is a valid JSON object or a valid JSON string + * @param object: the object to be checked + * @returns true if the object is a valid JSON object or a valid JSON string + */ +export function isValidJSONObject(object: any): boolean { + try { + JSON.parse(JSON.stringify(object)); + return true; + } catch (e) { + return false; + } +} diff --git a/src/index.ts b/src/index.ts index acb613d..7d49ee5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,8 +8,8 @@ import { } from './lib/locate'; import { show, head, tail } from './lib/display'; import { getSize, info } from './lib/info'; -import { flatten } from './lib/data'; -import { isArrayOfType, range } from './helpers/arrayFunctions'; +import { flatten, fromJSON } from './lib/data'; +import { isArrayOfType, range, flattenJSON } from './helpers/arrayFunctions'; class Izuku { rowdata: unknown[][] = []; @@ -61,6 +61,7 @@ class Izuku { public rangeIndex = (index: number) => { return rangeIndex(this, index); }; + public fromJSON = fromJSON; } class Frame extends Izuku { @@ -69,4 +70,4 @@ class Frame extends Izuku { } } -export { Frame, range }; +export { Frame, range, flattenJSON }; diff --git a/src/lib/data.ts b/src/lib/data.ts index dcc948b..9649d6d 100644 --- a/src/lib/data.ts +++ b/src/lib/data.ts @@ -1,3 +1,6 @@ +import { Frame } from '../index'; +import { isValidJSONObject } from '../helpers/arrayFunctions'; + /** * flattenArray - flattens a 2D into a single array * @param array: the array to be flattened @@ -14,3 +17,42 @@ export function flatten(array: any[][]): any[] { } return flattenedArray; } + +/** + * fromJSON - converts a JSON string into a rowdata - framedata is a 2D array + * @param json: the JSON string to be converted + * @returns the rowdata + */ +export function fromJSON(this: Frame, json: any): Frame { + if (isValidJSONObject(json)) { + const header: string[] = []; + const rowdata: any[][] = []; + // loop through each row + for (let i = 0; i < json.length; i++) { + // get all the keys and store them in the header + for (const key in json[i]) { + if (!header.includes(key)) { + header.push(key); + } + } + } + // loop through each row + for (let i = 0; i < json.length; i++) { + // get the values of the keys present in the header, if the values are not present in the row, add null + const row: any[] = []; + for (let j = 0; j < header.length; j++) { + if (json[i][header[j]] !== undefined) { + row.push(json[i][header[j]]); + } else { + row.push(null); + } + } + rowdata.push(row); + } + this.rowdata = rowdata; + this.columns = header; + return this; + } else { + throw new Error('Invalid JSON'); + } +} diff --git a/src/lib/display.ts b/src/lib/display.ts index 6aeb029..c33df70 100644 --- a/src/lib/display.ts +++ b/src/lib/display.ts @@ -40,7 +40,7 @@ function getTable( * @throws Error if the frame is empty */ export function show(this: Frame): void { - if (!this.rowdata.length) { + if (this.rowdata.length === 0) { throw new Error('Set data before printing'); } const numberOfRows = this.rowdata.length; @@ -74,7 +74,7 @@ export function show(this: Frame): void { * @throws Error if the frame is empty */ export function head(this: Frame, n = 5): void { - if (!this.rowdata.length) { + if (this.rowdata.length === 0) { throw new Error('Set data before printing'); } // Check if n is greater than the number of rows @@ -95,7 +95,7 @@ export function head(this: Frame, n = 5): void { * @throws Error if the frame is empty */ export function tail(this: Frame, n = 5): void { - if (!this.rowdata.length) { + if (this.rowdata.length === 0) { throw new Error('Set data before printing'); } // Check if n is greater than the number of rows diff --git a/src/lib/frame.ts b/src/lib/frame.ts index 8ed1316..d257fb4 100644 --- a/src/lib/frame.ts +++ b/src/lib/frame.ts @@ -63,12 +63,16 @@ export function setHeader(rowdata: any[][], header: any[]): Array<string> { */ export function generateHeader(rd: Array<any[]>): Array<string> { - const maxSizedArrayLength = rd.reduce((acc, curr) => { - return acc.length > curr.length ? acc : curr; - }).length; - const header: Array<string> = []; - for (let i = 0; i < maxSizedArrayLength; i++) { - header.push(`Column ${i + 1}`); + if (rd?.length) { + const maxSizedArrayLength = rd.reduce((acc, curr) => { + return acc.length > curr.length ? acc : curr; + }).length; + const header: Array<string> = []; + for (let i = 0; i < maxSizedArrayLength; i++) { + header.push(`Column ${i + 1}`); + } + return header; + } else { + return []; } - return header; } diff --git a/src/lib/info.ts b/src/lib/info.ts index 814992b..9338c75 100644 --- a/src/lib/info.ts +++ b/src/lib/info.ts @@ -17,58 +17,67 @@ export function getSize(rowdata: any[]): number { * @returns the type of data present in each column of the frame */ export function info(this: Frame): void { - const info: Array<any[]> = []; - info.push(['#', 'Column Name', 'Types', 'Empty Values']); - let counter = 0; - const countDataTypes = {} as any; - this.columns.forEach((column: string, index: number) => { - // get all the types of data in the column, do not repeat the same type - let nullValuesPresentInRow = false; - const columnDataTypes = this.rowdata.map((row: any[]) => { + if (this.rowdata.length === 0) { + throw new Error('Frame is empty'); + } else { + const info: Array<any[]> = []; + info.push(['#', 'Column Name', 'Types', 'Empty Values']); + let counter = 0; + const countDataTypes = {} as any; + this.columns.forEach((column: string, index: number) => { + // get all the types of data in the column, do not repeat the same type + let nullValuesPresentInRow = false; + const columnDataTypes = this.rowdata.map((row: any[]) => { + if ( + row[index] === null || + row[index] === undefined || + row[index] === '' + ) { + nullValuesPresentInRow = true; + } + const currentType = String(typeof row[index]); + if (!Object.keys(countDataTypes).includes(currentType)) { + Object.assign(countDataTypes, { [currentType]: 1 }); + } else { + const getKeyValue = <T, K extends keyof T>(obj: T, key: K): T[K] => + obj[key]; + const currentValue = getKeyValue(countDataTypes, currentType); + Object.assign(countDataTypes, { [currentType]: currentValue + 1 }); + } + return typeof row[index]; + }); + const uniqueDataTypes = [...new Set(columnDataTypes)]; + info.push([ + counter, + column, + [...uniqueDataTypes], + nullValuesPresentInRow + ]); + counter++; + }); + let dataTypesString = ''; + // Iterate through the countDataTypes object and create a string of the data types + Object.keys(countDataTypes).forEach((key: string) => { + dataTypesString += `${key}(${countDataTypes[key]})`; + // check if the key is not the last key in the object if ( - row[index] === null || - row[index] === undefined || - row[index] === '' + Object.keys(countDataTypes).indexOf(key) !== + Object.keys(countDataTypes).length - 1 ) { - nullValuesPresentInRow = true; - } - const currentType = String(typeof row[index]); - if (!Object.keys(countDataTypes).includes(currentType)) { - Object.assign(countDataTypes, { [currentType]: 1 }); - } else { - const getKeyValue = <T, K extends keyof T>(obj: T, key: K): T[K] => - obj[key]; - const currentValue = getKeyValue(countDataTypes, currentType); - Object.assign(countDataTypes, { [currentType]: currentValue + 1 }); + dataTypesString += ', '; } - return typeof row[index]; }); - const uniqueDataTypes = [...new Set(columnDataTypes)]; - info.push([counter, column, [...uniqueDataTypes], nullValuesPresentInRow]); - counter++; - }); - let dataTypesString = ''; - // Iterate through the countDataTypes object and create a string of the data types - Object.keys(countDataTypes).forEach((key: string) => { - dataTypesString += `${key}(${countDataTypes[key]})`; - // check if the key is not the last key in the object - if ( - Object.keys(countDataTypes).indexOf(key) !== - Object.keys(countDataTypes).length - 1 - ) { - dataTypesString += ', '; - } - }); - console.log(`RangeIndex: ${this.size} elements, 0 to ${this.size - 1}`); - console.log( - `Shape: ${this.shape.split(' x ')[0].trim()} rows, ${this.shape - .split(' x ')[1] - .trim()} columns` - ); - console.log(table(info)); - // Remove the previous printed newline - process.stdout.write('\x1B[1A\x1B[2K'); - console.log(`Data Types: ${dataTypesString}`); - console.log(`Memory Usage: ${sizeof(this)} bytes`); + console.log(`RangeIndex: ${this.size} elements, 0 to ${this.size - 1}`); + console.log( + `Shape: ${this.shape.split(' x ')[0].trim()} rows, ${this.shape + .split(' x ')[1] + .trim()} columns` + ); + console.log(table(info)); + // Remove the previous printed newline + process.stdout.write('\x1B[1A\x1B[2K'); + console.log(`Data Types: ${dataTypesString}`); + console.log(`Memory Usage: ${sizeof(this)} bytes`); + } } |
