Skip to content

Instantly share code, notes, and snippets.

@chrispsn
Created April 28, 2018 08:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrispsn/3c0183d9db165fc4e697bc16eee33937 to your computer and use it in GitHub Desktop.
Save chrispsn/3c0183d9db165fc4e697bc16eee33937 to your computer and use it in GitHub Desktop.
Restructuring Table as a class.
class Table extends Array {
static get [Symbol.species]() { return Array; } // Fixes map method
constructor() {
super();
Object.defineProperty(this, '_iteratorPairs', {value: []});
Object.defineProperty(this, '_headings', {value: []});
for (let {heading:h, iterable:i} of arguments) {
this._headings.push(h);
this._iteratorPairs.push([h, i[Symbol.iterator]()]);
Object.defineProperty(this, h, {get: () => this.map(r => r[h])});
};
}
_eval() {
Object.defineProperty(this, '_evaled', {value: true});
if (this._iteratorPairs.length === 0) return this;
let row, done = false;
for (;;) {
this.push(row = {});
for (let [h, iterator] of this._iteratorPairs) {
Object.defineProperty(row, h, {
configurable: true, // We delete the prop later
get() {
const item = iterator.next();
if (item.done) {done = true; return}
delete this[h]; return this[h] = item.value;
}
});
}
for (let h of this._headings) { row[h] } // Calculate props in row
if (done) {this.pop(); return this}
}
}
};
let t = new Table(
{heading: "icons", iterable: ["apple", "banana", "grape"]},
{heading: "revenue", iterable: [123, 456, 789]},
)
t._eval();
console.log(t);
console.log("t.icons:", t.icons);
t.forEach(v => console.log("Value via forEach:", v))
t.map(v => console.log("Value via map:", v));
console.log("Table iteration:", ...t);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment