import { type } from "os"; interface CsvReadOptions { delimiter?: string; rowDelimiter?: string; head?: string[]; sanitizeWith?: RegExp } interface Dataframe { head: string[]; body: string[][]; print: (self: Dataframe, maxRows?: number, start?: number, only?: string[]) => void; describe: (self: Dataframe) => void } /** * id , name , age * 1 , ali , 22 * 4 , rehman , 32 * 5 , suleiman , 12 * 6 , shah , 16 */ const print = (self: Dataframe, maxRows = 10, start = 0, only?: string[]) => { const table: any[] = [] for (let index = start; index < self.body.length; index++) { if (index >= maxRows + start) break; const value = self.body[index] const object: any = {} let i = 0 self.head.forEach(label => { object[label] = value[i] i++ }) table.push(object as object) } console.table(table, only || self.head) } const main = (data: string, options?: CsvReadOptions) => { if (options?.sanitizeWith) { data = data.replace(options.sanitizeWith, "") } const array = data.split(options?.rowDelimiter || "\n") const head = options?.head || array[0].split(options?.delimiter || ",") if (!options?.head) { array.splice(0, 1) } const dataFrameRawRepresentation = array.map(el => { return el.split(options?.delimiter || ",") }) const describe = (self: Dataframe) => { const table: any = {} head.forEach((label, index) => { let total = 0 const datas = self.body.map(el => { const ret: any = el[index] if (isNaN(ret)) return ret const num = parseFloat(ret) total += num return num }) const length = datas.length const median = length % 2 !== 0 ? datas[(length - 1) / 2] : ((datas[(length - 2) / 2]) + (datas[(length + 2) / 2])) / 2 table[label] = { entries: length, mid: datas[Math.floor(length / 2)], random: datas[Math.floor(Math.random() * length)], average: total / length, median, } }) console.table(table) } const dataFrame: Dataframe = { head: head, body: dataFrameRawRepresentation, print: print, describe: describe } return dataFrame } export default main export type { Dataframe, CsvReadOptions }