@@ -4,6 +4,7 @@ import type Jsonable from '../Contracts/Jsonable';
4
4
import LogicException from '../Exceptions/LogicException' ;
5
5
import { isObjectLiteral } from './function' ;
6
6
import type { MaybeArray } from './type' ;
7
+ import InvalidOffsetException from '../Exceptions/InvalidOffsetException' ;
7
8
8
9
export default class Collection < T > implements Jsonable , Arrayable < T > , Iterable < T > , ArrayLike < T > {
9
10
/**
@@ -296,7 +297,7 @@ export default class Collection<T> implements Jsonable, Arrayable<T>, Iterable<T
296
297
}
297
298
298
299
/**
299
- * Remove all items the are deep equal to the argument.
300
+ * Remove all items that are deep equal to the argument.
300
301
*
301
302
* @param {any } item
302
303
*
@@ -314,7 +315,7 @@ export default class Collection<T> implements Jsonable, Arrayable<T>, Iterable<T
314
315
* @return {this }
315
316
*/
316
317
public nth ( every : number ) : this {
317
- return this . _newInstance ( this . toArray ( ) . filter ( ( _item , index ) => ( index + 1 ) % every === 0 ) ) ;
318
+ return this . filter ( ( _item , index ) => ( index + 1 ) % every === 0 ) ;
318
319
}
319
320
320
321
/**
@@ -323,7 +324,7 @@ export default class Collection<T> implements Jsonable, Arrayable<T>, Iterable<T
323
324
* @return {this }
324
325
*/
325
326
public withoutEmpty ( ) : this {
326
- return this . _newInstance ( this . toArray ( ) . filter ( item => item !== undefined && item !== null ) ) ;
327
+ return this . filter ( item => item !== undefined && item !== null ) ;
327
328
}
328
329
329
330
/**
@@ -415,7 +416,7 @@ export default class Collection<T> implements Jsonable, Arrayable<T>, Iterable<T
415
416
? values
416
417
: new Collection ( Array . isArray ( values ) ? values : [ values ] ) ;
417
418
418
- return this . _newInstance ( this . toArray ( ) . filter ( item => argCollection . includes ( item ) ) ) ;
419
+ return this . filter ( item => argCollection . includes ( item ) ) ;
419
420
}
420
421
421
422
/**
@@ -435,12 +436,47 @@ export default class Collection<T> implements Jsonable, Arrayable<T>, Iterable<T
435
436
continue ;
436
437
}
437
438
438
- result . push ( this . _newInstance ( this . slice ( start , start + size ) . toArray ( ) ) ) ;
439
+ result . push ( this . slice ( start , start + size ) ) ;
439
440
}
440
441
441
442
return new Collection ( result ) ;
442
443
}
443
444
445
+ /**
446
+ * Chunk the collection by the specified key.
447
+ */
448
+ public chunkBy < K extends keyof T > ( key : K | ( ( item : T ) => PropertyKey ) ) : Record < PropertyKey , Collection < T > > {
449
+ if ( ! this . _allAreObjects ( ) ) {
450
+ throw new TypeError ( 'Every item needs to be an object to be able to access its properties.' ) ;
451
+ }
452
+
453
+ const result : Record < PropertyKey , Collection < T > > = { } ;
454
+
455
+ if ( typeof key === 'string' || typeof key === 'number' || typeof key === 'symbol' ) {
456
+ if ( ! this . every ( obj => key in obj ) ) {
457
+ throw new InvalidOffsetException (
458
+ '\'' + String ( key ) + '\' is not present in every item of the collection.'
459
+ ) ;
460
+ }
461
+
462
+ this . pluck ( String ( key ) ) . unique ( ) . forEach ( value => {
463
+ result [ value as PropertyKey ] = this . filter ( item => item [ key ] === value ) ;
464
+ } ) ;
465
+ } else {
466
+ this . forEach ( item => {
467
+ const propertyKey = key ( item ) ;
468
+
469
+ if ( ! result . hasOwnProperty ( propertyKey ) ) {
470
+ result [ propertyKey ] = new Collection ( ) ;
471
+ }
472
+
473
+ result [ propertyKey ] ! . push ( item ) ;
474
+ } ) ;
475
+ }
476
+
477
+ return result ;
478
+ }
479
+
444
480
/**
445
481
* Call a callback on the collection
446
482
* when the first argument is Boolean(true) or
@@ -535,18 +571,13 @@ export default class Collection<T> implements Jsonable, Arrayable<T>, Iterable<T
535
571
return this ;
536
572
}
537
573
538
- const array = this . toArray ( ) ;
539
-
540
574
if ( count < 0 ) {
541
- return this . _newInstance (
542
- array
543
- . reverse ( )
544
- . filter ( ( _item , index ) => index + 1 <= Math . abs ( count ) )
545
- . reverse ( )
546
- ) ;
575
+ return this . reverse ( )
576
+ . filter ( ( _item , index ) => index + 1 <= Math . abs ( count ) )
577
+ . reverse ( ) ;
547
578
}
548
579
549
- return this . _newInstance ( array . filter ( ( _item , index ) => index + 1 <= count ) ) ;
580
+ return this . filter ( ( _item , index ) => index + 1 <= count ) ;
550
581
}
551
582
552
583
/**
@@ -600,18 +631,13 @@ export default class Collection<T> implements Jsonable, Arrayable<T>, Iterable<T
600
631
return this . _newInstance ( this . toArray ( ) ) ;
601
632
}
602
633
603
- const array = this . toArray ( ) ;
604
-
605
634
if ( count < 0 ) {
606
- return this . _newInstance (
607
- array
608
- . reverse ( )
609
- . filter ( ( _item , index ) => index >= Math . abs ( count ) )
610
- . reverse ( )
611
- ) ;
635
+ return this . reverse ( )
636
+ . filter ( ( _item , index ) => index >= Math . abs ( count ) )
637
+ . reverse ( ) ;
612
638
}
613
639
614
- return this . _newInstance ( array . filter ( ( _item , index ) => index >= count ) ) ;
640
+ return this . filter ( ( _item , index ) => index >= count ) ;
615
641
}
616
642
617
643
/**
@@ -663,23 +689,20 @@ export default class Collection<T> implements Jsonable, Arrayable<T>, Iterable<T
663
689
public pluck < Keys extends Readonly < string [ ] > | string [ ] > ( properties : Keys ) : Collection < Record < Keys [ number ] , any > > ;
664
690
public pluck ( properties : MaybeArray < string > ) : Collection < any > {
665
691
if ( ! this . _allAreObjects ( ) ) {
666
- throw new TypeError ( 'Every item needs to be an object to be able to access its properties' ) ;
692
+ throw new TypeError ( 'Every item needs to be an object to be able to access its properties. ' ) ;
667
693
}
668
694
669
695
if ( Array . isArray ( properties ) ) {
670
- return new Collection (
671
- this . map ( ( item : Record < string , unknown > ) => {
672
- const obj : Record < string , unknown > = { } ;
696
+ return this . map ( ( item : Record < string , unknown > ) => {
697
+ const obj : Record < string , unknown > = { } ;
673
698
674
- properties . forEach ( property => obj [ property ] = item [ property ] ) ;
699
+ properties . forEach ( property => obj [ property ] = item [ property ] ) ;
675
700
676
- return obj ;
677
- } )
678
- . toArray ( )
679
- ) ;
701
+ return obj ;
702
+ } ) ;
680
703
}
681
704
682
- return new Collection ( this . map ( ( item : Record < string , unknown > ) => item [ properties ] ) . toArray ( ) ) ;
705
+ return this . map ( ( item : Record < string , unknown > ) => item [ properties ] ) ;
683
706
}
684
707
685
708
/**
@@ -752,7 +775,7 @@ export default class Collection<T> implements Jsonable, Arrayable<T>, Iterable<T
752
775
}
753
776
754
777
/**
755
- * Get the summative of the collection values.
778
+ * Get summative of the collection values.
756
779
*
757
780
* @param {string|function } key
758
781
*/
0 commit comments