-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy patharray-tools.js
261 lines (250 loc) · 7.03 KB
/
array-tools.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
//push into array if it does match another item
export function arrayPushNoDupe(array, item) {
if (array.indexOf(item) == -1) {
array.push(item);
}
}
//removes matching items from array
export function arrayRemoveWhere(array, whereFunction) {
var remaining = [];
for (var i = 0; i < array.length; i++) {
if (!whereFunction(array[i])) {
remaining.push(array[i]);
}
}
return remaining;
}
//replaces matching elements
export function arrayReplaceWhere(array, whereFunction, newValue) {
var resultArray = array.slice(0);
for (var i = 0; i < resultArray.length; i++) {
if (whereFunction(resultArray[i])) {
resultArray.splice(i, 1, newValue);
}
}
return resultArray;
}
//gets all matching indexes
//ES6 map with index
export function arrayFindIndices(array, whereFunction) {
var matches = [];
for (var i = 0; i < array.length; i++) {
if (whereFunction(array[i])) {
matches.push(i);
}
}
return matches;
}
//does a function for each element
//ES6 forEach but returns for chaining
export function arrayDo(array, eachFunction) {
for (var i = 0; i < array.length; i++) {
eachFunction(array[i]);
}
return array;
}
//counts matching items
export function arrayCount(array, countFunction) {
var count = 0;
for (var i = 0; i < array.length; i++) {
if (countFunction(array[i])) {
count += 1;
}
}
return count;
}
//gets page from array
export function arrayPage(array, page, pageSize) {
var index = page * pageSize;
if (index >= array.length || index < 0) {
return null;
}
return array.slice(index, index + pageSize);
}
//returns intersection of 2 arrays
export function arrayIntersect(arrayA, arrayB) {
if (!arrayA || !arrayB) {
return [];
}
const resultArray = [];
for (let i = 0; i < arrayA.length; i++) {
if (arrayB.indexOf(arrayA[i]) != -1) {
resultArray.push(arrayA[i]);
}
}
return resultArray;
}
//do 2 arrays intersect?
export const arrayHasIntersect = (arrayA, arrayB) =>
arrayIntersect(arrayA, arrayB).length > 0;
//gets only unique items
//todo dictionary lookup
export function arrayUnique(array) {
const resultArray = [];
for (let i = 0; i < array.length; i++) {
if (resultArray.indexOf(array[i]) == -1) {
resultArray.push(array[i]);
}
}
return resultArray;
}
//totals value counts as an object { value : count }
export function arrayBucketCount(array) {
const totals = {};
for (let i = 0; i < array.length; i++) {
if (!totals[array[i]]) {
totals[array[i]] = 1;
} else {
totals[array[i]]++;
}
}
return totals;
}
//Gets next value that is closest (look ahead), defaults to biggest if out of range
export function arrayNextClosest(value, array) {
var valuesAhead = [];
for (var i = 0; i < array.length; i++) {
var distance = array[i] - value;
if (distance > 0) {
valuesAhead.push(array[i]);
}
}
var result = Math.min.apply(null, valuesAhead);
if (isFinite(result)) {
return result;
} else {
return Math.max.apply(null, array);
}
}
//Gets previous value that is closest (look behind), defaults to smallest if out of range
export function arrayPreviousClosest(value, array) {
var valuesBehind = [];
for (var i = 0; i < array.length; i++) {
var distance = array[i] - value;
if (distance < 0) {
valuesBehind.push(array[i]);
}
}
var result = Math.max.apply(null, valuesBehind);
if (isFinite(result)) {
return result;
} else {
return Math.min.apply(null, array);
}
}
//Gets the value from an array or if it doesn't exist get first
export function arrayValueOrFirst(value, array) {
var index = array.indexOf(value);
if (index != -1) {
return array[index];
} else {
return array[0];
}
}
export const arrayClone = array =>
Array.prototype.slice.call(array, 0);
export function arrayOrderBy(array, mapFunc) {
const newArray = array.slice(0);
newArray.sort(function(a, b) {
const valueA = mapFunc(a);
const valueB = mapFunc(b);
if (typeof(valueA) === "string") {
return valueA.localeCompare(valueB);
}
return valueA - valueB;
});
return newArray;
}
export function arrayUniqueBy(array, idFunc) {
const newArray = [];
const used = new Set();
for(let i = 0; i < array.length; i++){
const id = idFunc(array[i]);
if(!used.has(id)){
newArray.push(array[i]);
used.add(id);
}
}
return newArray;
}
//get an array of indices where the result of mapFunc changes
export function arrayChangeIndices(array, mapFunc) {
const currentValue = mapFunc(array[0]);
const indices = [];
for (let i = 1; i < array.length; i++) {
const value = mapFunc(array[i])
if (value !== currentValue) {
indices.push(i - 1);
currentValue = value;
}
}
return indices;
}
//merges two arrays of elements into a single array of merged objects
export function arrayZip(array, otherArray) {
const newArray = [];
const minLength = Math.min(array.length != otherArray.length);
for (let i = 0; i < minLength; i++) {
newArray.push({ ...array[i], ...otherArray[i] });
}
return newArray;
}
//Creates two arrays based on whether a mapping is true or false
export const arrayPartition = (array, filterFunc) =>
array.reduce((p, x) => {
if(filterFunc(x)){
p[0].push(x);
}else{
p[1].push(x);
}
return p;
}, [[],[]]);
//Chunks up the elements by count
export function arrayChunk(array, lengthPerChunk){
const result = [];
let chunk = [array[0]];
for(let i = 1; i < array.length; i++){
if(i % lengthPerChunk === 0){
result.push(chunk);
chunk = [];
}
chunk.push(array[i]);
}
if(chunk.length > 0) result.push(chunk);
return result;
}
export function arrayToTable(array, { headings } = {}){
const table = document.createElement("table");
let i = 0;
if(headings){
const thead = document.createElement("thead");
array[0].forEach(h => {
const th = document.createElement("th");
th.textContent = h;
thead.append(th);
});
table.append(thead);
i = 1;
}
const tbody = document.createElement("tbody");
for(;i < array.length;i++){
const tr = document.createElement("tr");
for(let j = 0; j < array[i].length; j++){
const td = document.createElement("td");
td.textContent = array[i][j];
tr.append(td);
}
tbody.append(tr);
}
table.appendChild(tbody);
return table;
}
export function getRange({ start, end, step }){
let i = start ?? 0;
step = step ?? 1;
const result = [];
for (; i <= end; i += step){
result.push(i);
}
return result;
}