import { deepCopy } from "../utils"; import { DataColumn } from "./DataColumn"; import { JSON2CSV, saveTextToFile } from "./utils"; export class DataCollection { private trials: any[]; constructor(data = []) { this.trials = data; } push(new_data) { this.trials.push(new_data); return this; } join(other_data_collection: DataCollection) { this.trials = this.trials.concat(other_data_collection.values()); return this; } top() { if (this.trials.length <= 1) { return this; } else { return new DataCollection([this.trials[this.trials.length - 1]]); } } /** * Queries the first n elements in a collection of trials. * * @param n A positive integer of elements to return. A value of * n that is less than 1 will throw an error. * * @return First n objects of a collection of trials. If fewer than * n trials are available, the trials.length elements will * be returned. * */ first(n = 1) { if (n < 1) { throw `You must query with a positive nonzero integer. Please use a different value for n.`; } if (this.trials.length === 0) return new DataCollection(); if (n > this.trials.length) n = this.trials.length; return new DataCollection(this.trials.slice(0, n)); } /** * Queries the last n elements in a collection of trials. * * @param n A positive integer of elements to return. A value of * n that is less than 1 will throw an error. * * @return Last n objects of a collection of trials. If fewer than * n trials are available, the trials.length elements will * be returned. * */ last(n = 1) { if (n < 1) { throw `You must query with a positive nonzero integer. Please use a different value for n.`; } if (this.trials.length === 0) return new DataCollection(); if (n > this.trials.length) n = this.trials.length; return new DataCollection(this.trials.slice(this.trials.length - n, this.trials.length)); } values() { return this.trials; } count() { return this.trials.length; } readOnly() { return new DataCollection(deepCopy(this.trials)); } addToAll(properties) { for (const trial of this.trials) { Object.assign(trial, properties); } return this; } addToLast(properties) { if (this.trials.length != 0) { Object.assign(this.trials[this.trials.length - 1], properties); } return this; } filter(filters) { // [{p1: v1, p2:v2}, {p1:v2}] // {p1: v1} let f; if (!Array.isArray(filters)) { f = deepCopy([filters]); } else { f = deepCopy(filters); } const filtered_data = []; for (const trial of this.trials) { let keep = false; for (const filter of f) { let match = true; for (const key of Object.keys(filter)) { if (typeof trial[key] !== "undefined" && trial[key] === filter[key]) { // matches on this key! } else { match = false; } } if (match) { keep = true; break; } // can break because each filter is OR. } if (keep) { filtered_data.push(trial); } } return new DataCollection(filtered_data); } filterCustom(fn) { return new DataCollection(this.trials.filter(fn)); } filterColumns(columns: Array) { return new DataCollection( this.trials.map((trial) => Object.fromEntries(columns.filter((key) => key in trial).map((key) => [key, trial[key]])) ) ); } select(column) { const values = []; for (const trial of this.trials) { if (typeof trial[column] !== "undefined") { values.push(trial[column]); } } return new DataColumn(values); } ignore(columns) { if (!Array.isArray(columns)) { columns = [columns]; } const o = deepCopy(this.trials); for (const trial of o) { for (const delete_key of columns) { delete trial[delete_key]; } } return new DataCollection(o); } uniqueNames() { const names = []; for (const trial of this.trials) { for (const key of Object.keys(trial)) { if (!names.includes(key)) { names.push(key); } } } return names; } csv() { return JSON2CSV(this.trials); } json(pretty = false) { if (pretty) { return JSON.stringify(this.trials, null, "\t"); } return JSON.stringify(this.trials); } localSave(format, filename) { format = format.toLowerCase(); let data_string; if (format === "json") { data_string = this.json(); } else if (format === "csv") { data_string = this.csv(); } else { throw new Error('Invalid format specified for localSave. Must be "json" or "csv".'); } saveTextToFile(data_string, filename); } }