@@ -130,37 +130,62 @@ namespace ts {
130
130
return - 1 ;
131
131
}
132
132
133
- export function countWhere < T > ( array : T [ ] , predicate : ( x : T ) => boolean ) : number {
133
+ export function countWhere < T > ( array : T [ ] , predicate : ( x : T , i : number ) => boolean ) : number {
134
134
let count = 0 ;
135
135
if ( array ) {
136
- for ( const v of array ) {
137
- if ( predicate ( v ) ) {
136
+ for ( let i = 0 ; i < array . length ; i ++ ) {
137
+ const v = array [ i ] ;
138
+ if ( predicate ( v , i ) ) {
138
139
count ++ ;
139
140
}
140
141
}
141
142
}
142
143
return count ;
143
144
}
144
145
145
- export function filter < T > ( array : T [ ] , f : ( x : T ) => boolean ) : T [ ] {
146
+ export function filter < T , U extends T > ( array : T [ ] , f : ( x : T , i : number ) => x is U ) : U [ ] ;
147
+ export function filter < T > ( array : T [ ] , f : ( x : T , i : number ) => boolean ) : T [ ] ;
148
+ export function filter < T > ( array : T [ ] , f : ( x : T , i : number ) => boolean ) : T [ ] {
146
149
let result : T [ ] ;
147
150
if ( array ) {
148
151
result = [ ] ;
149
- for ( const item of array ) {
150
- if ( f ( item ) ) {
151
- result . push ( item ) ;
152
+ for ( let i = 0 ; i < array . length ; i ++ ) {
153
+ const v = array [ i ] ;
154
+ if ( f ( v , i ) ) {
155
+ result . push ( v ) ;
152
156
}
153
157
}
154
158
}
155
159
return result ;
156
160
}
157
161
158
- export function map < T , U > ( array : T [ ] , f : ( x : T ) => U ) : U [ ] {
162
+ export function map < T , U > ( array : T [ ] , f : ( x : T , i : number ) => U ) : U [ ] {
159
163
let result : U [ ] ;
160
164
if ( array ) {
161
165
result = [ ] ;
162
- for ( const v of array ) {
163
- result . push ( f ( v ) ) ;
166
+ for ( let i = 0 ; i < array . length ; i ++ ) {
167
+ const v = array [ i ] ;
168
+ result . push ( f ( v , i ) ) ;
169
+ }
170
+ }
171
+ return result ;
172
+ }
173
+
174
+ /**
175
+ * Maps an array. If the mapped value is an array, it is spread into the result.
176
+ */
177
+ export function flatMap < T , U > ( array : T [ ] , f : ( x : T , i : number ) => U | U [ ] ) : U [ ] {
178
+ let result : U [ ] ;
179
+ if ( array ) {
180
+ result = [ ] ;
181
+ for ( let i = 0 ; i < array . length ; i ++ ) {
182
+ const v = array
F987
[ i ] ;
183
+ const ar = f ( v , i ) ;
184
+ if ( ar ) {
185
+ // We cast to <U> here to leverage the behavior of Array#concat
186
+ // which will append a single value here.
187
+ result = result . concat ( < U [ ] > ar ) ;
188
+ }
164
189
}
165
190
}
166
191
return result ;
@@ -172,18 +197,6 @@ namespace ts {
172
197
return [ ...array1 , ...array2 ] ;
173
198
}
174
199
175
- export function append < T > ( array : T [ ] , value : T ) : T [ ] {
176
- if ( value === undefined ) return array ;
177
- if ( ! array || ! array . length ) return [ value ] ;
178
- return [ ...array , value ] ;
179
- }
180
-
181
- export function prepend < T > ( array : T [ ] , value : T ) : T [ ] {
182
- if ( value === undefined ) return array ;
183
- if ( ! array || ! array . length ) return [ value ] ;
184
- return [ value , ...array ] ;
185
- }
186
-
187
200
export function deduplicate < T > ( array : T [ ] ) : T [ ] {
188
201
let result : T [ ] ;
189
202
if ( array ) {
@@ -197,6 +210,27 @@ namespace ts {
197
210
return result ;
198
211
}
199
212
213
+ /**
214
+ * Compacts an array, removing any falsey elements.
215
+ */
216
+ export function compact < T > ( array : T [ ] ) : T [ ] {
217
+ let result : T [ ] ;
218
+ if ( array ) {
219
+ for ( let i = 0 ; i < array . length ; i ++ ) {
220
+ const v = array [ i ] ;
221
+ if ( result || ! v ) {
222
+ if ( ! result ) {
223
+ result = array . slice ( 0 , i ) ;
224
+ }
225
+ if ( v ) {
226
+ result . push ( v ) ;
227
+ }
228
+ }
229
+ }
230
+ }
231
+ return result || array ;
232
+ }
233
+
200
234
export function sum ( array : any [ ] , prop : string ) : number {
201
235
let result = 0 ;
202
236
for ( const v of array ) {
@@ -223,15 +257,25 @@ namespace ts {
223
257
return true ;
224
258
}
225
259
260
+ export function firstOrUndefined < T > ( array : T [ ] ) : T {
261
+ return array && array . length > 0
262
+ ? array [ 0 ]
263
+ : undefined ;
264
+ }
265
+
266
+ export function singleOrUndefined < T > ( array : T [ ] ) : T {
267
+ return array && array . length === 1
268
+ ? array [ 0 ]
269
+ : undefined ;
270
+ }
271
+
226
272
/**
227
273
* Returns the last element of an array if non-empty, undefined otherwise.
228
274
*/
229
275
export function lastOrUndefined < T > ( array : T [ ] ) : T {
230
- if ( array . length === 0 ) {
231
- return undefined ;
232
- }
233
-
234
- return array [ array . length - 1 ] ;
276
+ return array && array . length > 0
277
+ ? array [ array . length - 1 ]
278
+ : undefined ;
235
279
}
236
280
237
281
/**
@@ -263,9 +307,9 @@ namespace ts {
263
307
return ~ low ;
264
308
}
265
309
266
- export function reduceLeft < T , U > ( array : T [ ] , f : ( memo : U , value : T ) => U , initial : U ) : U ;
267
- export function reduceLeft < T > ( array : T [ ] , f : ( memo : T , value : T ) => T ) : T ;
268
- export function reduceLeft < T > ( array : T [ ] , f : ( memo : T , value : T ) => T , initial ?: T ) : T {
310
+ export function reduceLeft < T , U > ( array : T [ ] , f : ( memo : U , value : T , i : number ) => U , initial : U ) : U ;
311
+ export function reduceLeft < T > ( array : T [ ] , f : ( memo : T , value : T , i : number ) => T ) : T ;
312
+ export function reduceLeft < T > ( array : T [ ] , f : ( memo : T , value : T , i : number ) => T , initial ?: T ) : T {
269
313
if ( array ) {
270
314
const count = array . length ;
271
315
if ( count > 0 ) {
@@ -279,7 +323,7 @@ namespace ts {
279
323
result = initial ;
280
324
}
281
325
while ( pos < count ) {
282
- result = f ( result , array [ pos ] ) ;
326
+ result = f ( result , array [ pos ] , pos ) ;
283
327
pos ++ ;
284
328
}
285
329
return result ;
@@ -288,9 +332,9 @@ namespace ts {
288
332
return initial ;
289
333
}
290
334
291
- export function reduceRight < T , U > ( array : T [ ] , f : ( memo : U , value : T ) => U , initial : U ) : U ;
292
- export function reduceRight < T > ( array : T [ ] , f : ( memo : T , value : T ) => T ) : T ;
293
- export function reduceRight < T > ( array : T [ ] , f : ( memo : T , value : T ) => T , initial ?: T ) : T {
335
+ export function reduceRight < T , U > ( array : T [ ] , f : ( memo : U , value : T , i : number ) => U , initial : U ) : U ;
336
+ export function reduceRight < T > ( array : T [ ] , f : ( memo : T , value : T , i : number ) => T ) : T ;
337
+ export function reduceRight < T > ( array : T [ ] , f : ( memo : T , value : T , i : number ) => T , initial ?: T ) : T {
294
338
if ( array ) {
295
339
let pos = array . length - 1 ;
296
340
if ( pos >= 0 ) {
@@ -303,7 +347,7 @@ namespace ts {
303
347
result = initial ;
304
348
}
305
349
while ( pos >= 0 ) {
306
- result = f ( result , array [ pos ] ) ;
350
+ result = f ( result , array [ pos ] , pos ) ;
307
351
pos -- ;
308
352
}
309
353
return result ;
0 commit comments