-
Notifications
You must be signed in to change notification settings - Fork 1
/
output.js
127 lines (95 loc) · 3.15 KB
/
output.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
var maxTableWidth = 200;
function combinedHeader(contacts) {
return contacts.reduce(function (prev, cur) {
Object.keys(cur).forEach(function(key) {
if (prev.indexOf(key) === -1) prev.push(key);
});
return prev;
},[]);
}
function displayWidth(str) {
str = str.toString();
var ret = str.length;
for (var i = 0; i < str.length; i++)
if (str.charCodeAt(i) > 255)
ret++;
return ret;
}
function displaySubString(str, len) {
var firstHalf = '';
for (var i = 0; i < str.length && displayWidth(firstHalf) < len; i++)
firstHalf += str[i];
return [str.substring(0, i - 1), str.substring(i - 1)];
}
function max(arr) {
return arr.reduce(function(prev, cur) {
return prev >= cur ? prev : cur;
}, 0);
}
function repeat(ch, count) {
var ret = '';
for (var i = 0; i < count ; i++) {
ret += ch;
}
return ret;
}
function tablizeLine(people, maxColWidthArr) {
var peopleRemaining = people.map(function() { return ''; });
var peopleInCell = '| ' +
people.map(function(v, i) {
if (displayWidth(v) > maxColWidthArr[i]) {
peopleRemaining[i] = displaySubString(v, maxColWidthArr[i])[1];
v = displaySubString(v, maxColWidthArr[i])[0]
}
return v + repeat(' ', maxColWidthArr[i] - displayWidth(v));
}).join(' | ') + ' |'
if (peopleRemaining.reduce(function(prev, cur) {return prev + cur; }, '').trim().length > 0) {
peopleInCell += '\n' + tablizeLine(peopleRemaining, maxColWidthArr);
}
return peopleInCell;
}
function sepLine(maxColWidthArr) {
return '+-' +
maxColWidthArr.map(function(v) {
return repeat('-', v);
}).join('-+-') + '-+'
}
function trimColWidthArr(maxColWidthArr, totalColWidth) {
var extraWidth = totalColWidth - maxTableWidth;
var averageWidth = Math.floor(maxTableWidth/maxColWidthArr.length);
var longColArr = maxColWidthArr.map(function(v) {
return v > averageWidth ? v : 0;
});
var longColArrSum = longColArr.reduce(function(prev, cur) {return prev + cur; }, 0);
var trimmedColWidthArr1 = maxColWidthArr.map(function(v, i) {
return Math.ceil((longColArr[i]/longColArrSum) * extraWidth);
});
var trimmedColWidthArr = maxColWidthArr.map(function(v, i) {
return v - Math.ceil((longColArr[i]/longColArrSum) * extraWidth);
});
return trimmedColWidthArr;
}
function print(contacts) {
var header = combinedHeader(contacts);
var tableLineArr = contacts.map(function(people) {
return header.map(function(headerKey) {
return people[headerKey] || '';
});
});
tableLineArr.unshift(header);
var maxColWidthArr = header.map(function(v, i) {
var columnWitdh = tableLineArr.map(function(v) { return displayWidth(v[i]); });
return max(columnWitdh);
});
var totalColWidth = maxColWidthArr.reduce(function(prev, cur) {
return prev + cur + 3;
}, 1);
if (totalColWidth > maxTableWidth) {
maxColWidthArr = trimColWidthArr(maxColWidthArr, totalColWidth);
}
var tableStr = tableLineArr.reduce(function(prev, cur) {
return prev + tablizeLine(cur, maxColWidthArr) + '\n' + sepLine(maxColWidthArr) + '\n';
}, sepLine(maxColWidthArr) + '\n');
console.log(tableStr);
}
exports.print = print;