|
| 1 | +'use strict'; |
| 2 | + |
| 3 | +// Projection |
| 4 | + |
| 5 | +const id = x => x; |
| 6 | + |
| 7 | +const projection = meta => src => meta.reduce( |
| 8 | + (dest, [name, fn = id, field = name]) => |
| 9 | + (dest[name] = fn(src[field]), dest), {} |
| 10 | +); |
| 11 | + |
| 12 | +// Display |
| 13 | + |
| 14 | +const max = items => Math.max(...items); |
| 15 | +const maxProp = key => items => max(items.map(x => x[key])); |
| 16 | +const maxLength = maxProp('length'); |
| 17 | +const col = (name, data) => data.map(obj => obj[name].toString()); |
| 18 | + |
| 19 | +const render = meta => src => { |
| 20 | + const keys = meta.map(([name]) => name); |
| 21 | + const maxWidth = keys.map(key => maxLength(col(key, src))); |
| 22 | + const dest = src.map(obj => maxWidth.map( |
| 23 | + (width, i) => obj[keys[i]].toString().padEnd(width + 4) |
| 24 | + )); |
| 25 | + return dest.map(row => row.join('')).join('\n'); |
| 26 | +}; |
| 27 | + |
| 28 | +// Dataset |
| 29 | + |
| 30 | +const persons = [ |
| 31 | + { name: 'Marcus Aurelius', city: 'Rome', born: 121 }, |
| 32 | + { name: 'Victor Glushkov', city: 'Rostov on Don', born: 1923 }, |
| 33 | + { name: 'Ibn Arabi', city: 'Murcia', born: 1165 }, |
| 34 | + { name: 'Mao Zedong', city: 'Shaoshan', born: 1893 }, |
| 35 | + { name: 'Rene Descartes', city: 'La Haye en Touraine', born: 1596 }, |
| 36 | +]; |
| 37 | + |
| 38 | +// Metadata |
| 39 | + |
| 40 | +const year = date => date.getFullYear(); |
| 41 | +const diff = y => year(new Date()) - year(new Date(y + '')); |
| 42 | +const upper = s => s.toUpperCase(); |
| 43 | + |
| 44 | +const md = [ |
| 45 | + ['name'], |
| 46 | + ['place', upper, 'city'], |
| 47 | + ['age', diff, 'born'], |
| 48 | +]; |
| 49 | + |
| 50 | +const query = person => ( |
| 51 | + person.name !== '' && |
| 52 | + person.born < 1900 && |
| 53 | + person.city === 'Rome' |
| 54 | +); |
| 55 | + |
| 56 | +// Usage |
| 57 | + |
| 58 | +const pf = projection(md); |
| 59 | +const data = persons.filter(query).map(pf); |
| 60 | + |
| 61 | +const renderer = render(md); |
| 62 | +const res = renderer(data); |
| 63 | +console.log('\n' + res + '\n'); |
0 commit comments