Collection
The collection is an object an implementing ArrayLike and Iterable meaning it can be iterated with for... of or generators, has a .length property, and it can be indexed by numbers collection[0]. It implements all method available on the array in a compatible fashion. The collection is immutable unless the methods that are expected to mutate the collection: push, pop, unshift, shift, fill.
* Despite feature parity, the type of the collection isn't interchangeable with the array given some methods are returning a collection instead of array, for example map.
Instantiating a new collection is easy as:
import { Collection, collect } from '@upfrontjs/framework'
collect([1, 2, 3]);
// or
new Collection([1, 2, 3])
The constructor can take a single argument of an item or array of items or no argument.
WARNING
Note on extending the collection.
Given the collection is immutable it creates a new instance on method calls. If you're extending the collection, and your constructor takes a non-optional nth argument, the inherited methods will not work as it's impossible to tell what extra arguments might be needed.
Methods
first
The first method returns the first element of the collection. Optionally it takes a function to pick the first element by. If the collection is empty, it returns undefined.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.first(); // 1
collection.first(number => number > 2); // 3
last
The last method returns the last element in the collection. Optionally it takes a function to pick the last element by. If the collection is empty, it returns undefined.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.last(); // 5
collection.first(number => number < 5); // 4
random
The random method returns a random element from the collection. Optionally you may specify the number of random elements to pick. The argument's absolute value is used in case of negative integers.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.random(); // random element 
collection.random(2); // collection of 2 random elements
collection.random(collection.length); // return the whole collection
shuffle
The shuffle method returns the collection with the items in a randomised order.
import { Collection } from '@upfrontjs/framework';
const numCollection = new Collection([1, 2, 3, 4, 5]);
numCollection.shuffle(); // Collection[3, 1, 4, 2, 5]
numCollection.shuffle(); // Collection[2, 5, 1, 4, 3]
is
The is method determines if the collection is equal to the given collection. It uses deep equality to ensure every element in the collection is equal to the given collection in the same order.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.is(collection); // true
collection.is(new Collection([1, 2, 3, 4, 5])); // true
collection.is(collection.slice(0, 1)); // false
(new Collection([{ id: 1 }])).is(new Collection([{ id: 2 }])); // false
isEmpty
The isEmpty method determines whether the collection is empty or not.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.isEmpty(); // false
(new Collection).isEmpty(); // true
isNotEmpty
The isNotEmpty method determines whether the collection is not empty or is empty.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.isNotEmpty(); // true
(new Collection).isNotEmpty(); // false
hasDuplicates
The hasDuplicates method determines if there are any duplicates in the collection based on deep equality.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.hasDuplicates(); // false
(new Collection([1, 1])).hasDuplicates(); // true
unique
The unique method de-duplicates the collection based on deep equality. Optionally it takes one argument which is a string or function. On a function argument, the equality will be evaluated based on the function's return value. If the given argument is a string and all items in the collection are objects then if the object's key matching the string it will be based on the value's deep equality.
import { Collection } from '@upfrontjs/framework';
let collection = new Collection([1, 2, 1, 4, 5]);
collection.unique(); // Collection[1, 2, 4, 5]
collection = new Collection([
    { id: 1, name: 'name1' },
    { id: 2, name: 'name2' },
    { id: 3, name: 'name1' },
]);
collection.unique('name'); // Collection[{ id: 1, name: 'name1' },{ id: 2, name: 'name2' }]
collection.unique(obj => object.name); // Collection[{ id: 1, name: 'name1' },{ id: 2, name: 'name2' }]
duplicates
The duplicates method returns only the duplicates from the collection. Optionally it takes one argument which is a string or function. On a function argument, the equality will be evaluated based on the function's return value. If the given argument is a string and all items in the collection are objects then if the object's key matching the string it will be based on the value's deep equality.
import { Collection } from '@upfrontjs/framework';
let collection = new Collection([1, 2, 1, 4, 5]);
collection.duplicates(); // Collection[1]
collection = new Collection([
    { id: 1, name: 'name1' },
    { id: 2, name: 'name2' },
    { id: 3, name: 'name1' }
]);
collection.duplicates('name'); // Collection[{ id: 1, name: 'name1' }]
collection.duplicates(obj => object.name); // Collection[{ id: 1, name: 'name1' }]
delete
The delete method removes all elements that deep equal to the given value;
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.delete(3); // Collection[1, 2, 4, 5]
nth
The nth method returns only every nth item in the collection.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.nth(2); // Collection[2, 4]
withoutEmpty
The withoutEmpty method filters out every null and undefined values from the collection.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, null, 3, 4, 5, undefined]);
collection.withoutEmpty(); // Collection[1, 2, 3, 4, 5]
pad
The pad method pads the collection to the given length with the given optional value. The value if it's a function, will be called. If the given length is a negative integer the value will be prepended.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3]);
collection.pad(5); // Collection[1, 2, 3, undefined, undefined]
collection.pad(1); // Collection[1, 2, 3]
collection.pad(-5); // Collection[undefined, undefined, 1, 2, 3]
collection.pad(4, 'value'); // Collection[1, 2, 3, 'value']
collection.pad(4, () => 'return value'); // Collection[1, 2, 3, 'return value']
union
The union method joins one or more iterables without overlapping values based on deep equality.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.union(1, [4, 6], new Collection(7)); // Collection[1, 2, 3, 4, 5, 6, 7]
diff
The diff method returns the difference between the collection and the given item or array/collection based on deep equality.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.diff([2, 3, 4, 5, 6]); // Collection[1, 6]
collection.diff(1); // Collection[2, 3, 4, 5]
intersect
The intersect method returns the values that are present in both the collection, and the given value.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.intersect(1); // Colection[1]
collection.intersect(new Collection([3, 4, 5, 6])); // Colection[3, 4, 5]
chunk
The chunk method returns a collection of collections with the given size.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.chunk(2); // Collection[Collection[1, 2], Collection[3, 4], Collection[5]]
collection.chunk(5); // Collection[Collection[1, 2, 3, 4, 5]]
chunkBy
The chunkBy method returns an object where the keys are the resolved key values. The method also accepts a callback function which can be used to chunk by deeply nested key values.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([
    { id: 0, parentId: 5 },
    { id: 1, parentId: 5 },
    { id: 2, parentId: 3 },
    { id: 3, parentId: 3 },
    { id: 4, parentId: 3 }
]);
/**
 * Will result in:
 * {
 *     '5': Collection[{ id: 0, parentId: 5 },{ id: 1, parentId: 5 }],
 *     '3': Collection[{ id: 2, parentId: 3 },{ id: 3, parentId: 3 },{ id: 4, parentId: 3 }],
 * }
 */
collection.chunkBy('parentId');
/**
 * Will result in:
 * {
 *     '5': Collection[{ id: 0, parentId: 5 },{ id: 1, parentId: 5 }],
 *     '3': Collection[{ id: 2, parentId: 3 },{ id: 3, parentId: 3 },{ id: 4, parentId: 3 }],
 * }
 */
collection.chunkBy(item => item.parentKey);
when
The when method executes the given method if the first argument evaluates to true. The method has to return the collection.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.when(true, collectionCopy => collectionCopy.nth(2)); // Collection[2, 4]
collection.when(() => false, collectionCopy => collectionCopy.nth(2)); // Collection[1, 2, 3, 4, 5]
unless
The unless method executes the given method if the first argument evaluates to false. The method has to return the collection.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.unless(false, collectionCopy => collectionCopy.nth(2)); // Collection[2, 4]
collection.unless(() => true, collectionCopy => collectionCopy.nth(2)); // Collection[1, 2, 3, 4, 5]
whenEmpty
The whenEmpty method executes the given method if the collection is empty.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
let count = 0;
collection.whenEmpty(collectionCopy => count++);
count; // 0
(new Collection).whenEmpty(collectionCopy => count++);
count; // 1
whenNotEmpty
The whenNotEmpty method executes the given method when the collection is not empty.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
let count = 0;
collection.whenNotEmpty(collectionCopy => count++);
count; // 1
(new Collection).whenNotEmpty(collectionCopy => count++);
count; // 1
take
The take method returns given number of items. On negative integer, it returns items from the end first.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.take(2); // Collection[1, 2]
collection.take(-2); // Collection[4, 5]
takeUntil
The takeUntil method takes items from the collection until the given function called with the item returns false.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.takeUntil(item => item >= 4); // Collection[1, 2, 3]
takeWhile
The takeWhile method takes items from the collection until the given function called with the item returns true.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.takeWhile(item => item < 4); // Collection[1, 2, 3]
skip
The skip method skips the given number of items in the collection.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.skip(3); // Collection[4, 5]
skipUntil
The skipUntil method skips items until the given function returns false.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.skipUntil(item => item > 2); // Collection[3, 4, 5]
skipWhile
The skipWhile method skips items until the given function returns true.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.skipWhile(item => item <= 2); // Collection[3, 4, 5]
partition
The partition method separates the items into two collections based on the given callback's boolean value.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
const [
    failingPartition, // Collection([1, 2, 3]))
    pasingPartition // Collection([4, 5])
] = collection.partition(item => item > 3);
pluck
When all items in the collections are objects then you may use to The pluck method to get certain attributes in a collection or multiple attributes in a collection of objects. Similarly to dataGet You may also use dot notation.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection(
    { id: 1, name: 'name1', email: 'test1@email.com', property: { key: 'value1' } },
    { id: 2, name: 'name2', email: 'test2@email.com', property: { key: 'value2' } },
    { id: 3, name: 'name3', email: 'test3@email.com', property: { key: 'value3' } },
);
collection.pluck('name'); // Collection['name1', 'name2', 'name3']
collection.pluck(['id', 'name']); // Collection[{ id: 1, name: 'name1' }, { id: 2, name: 'name2' }, { id: 3, name: 'name3' }]
collection.pluck('property.key'); // Collection['value1', 'value2', 'value3']
collection.pluck(['property.key', 'id']); // Collection[{ id: 1, 'property.key': 'value1' }, { id: 2, 'property.key': 'value2' }, { id: 3, 'property.key': 'value3' }]
tap
The tap method executes the given function with the collection without changing the collection.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.tap(collectionCopy => collection.take(2)); // Collection([1, 2, 3, 4, 5])
pipe
The pipe method executes the given function with the collection. The function must return the collection.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.pipe(collectionCopy => collection.take(2)); // Collection([1, 2])
dump
The dump method is a debugging function which prints out the collection in its current state to the console. It is chainable. Optionally it can take a message argument.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.dump(); // logged: '10:37:05 - All items: 1,2,3,4,5'
collection.dump('test'); // logged: '10:37:05 (test) - All items: 1,2,3,4,5'
collection.dump().take(2); // Collection[1, 2]
orderBy
When all items in the collections are objects, then you may order them using the orderBy method. The method takes one or more objects describing how the collection should be ordered. The object has two properties:
- property- the name of the property you want to order by OR a method that accepts the collection item and returns the nested value.
- direction- possible values are- asc,- descrespective to whether it should be in ascending or descending order.
const elements = [
    { id: 2, nestedObj: { name: '2' } },
    { id: 1, nestedObj: { name: '5' } },
    { id: 1, nestedObj: { name: '1' } },
    { id: 4, nestedObj: { name: '4' } },
    { id: 3, nestedObj: { name: '3' } }
];
const collection = new Collection(elements);
collection.orderBy(
    { property: 'id', directions: 'asc' },
    { property: element => element.nestedObj.name, direction: 'desc' }
).at(1)!.nestedObj.name === '1'; // true
collection.orderBy(
    { property: element => element.nestedObj.name, direction: 'asc' }
).at(0)!.nestedObj.name === '1'; // true
toArray
The toArray method creates an array from the collection.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.toArray(); // [1, 2, 3, 4, 5]
toJSON
The toJSON method returns the JSON representation of the collection.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.toJSON(); // '{"0":1,"1":2,"2":3,"3":4,"4":5,"length":5}'
isCollection
staticThe isCollection static method is used to evaluate whether the given value is a collection.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
Collection.isCollection(collection); // true
Collection.isCollection(1); // false
times
staticThe times static method is used to create a new collection consisting of the given value with the given number of times. A function may also be passed which will be called with the current iteration (iteration starting at 1).
import { Collection } from '@upfrontjs/framework';
Collection.times(3, 'value'); // Collection['value', 'value', 'value']
Collection.times(3, i => i); // Collection[1, 2, 3]
forEach
The forEach works the same way as the base forEach, except it is chainable.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2, 3, 4, 5]);
collection.forEach(number => console.log(number)).take(2); // Collection([1, 2])
includes
The includes works the same way as the base includes, except it evaluates based on deep equality.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([{ id: 1 }, { id: 2 }]);
collection.include({ id: 2 }); // true
collection.include(2); // false
join
The join method works the same way the base join, except when using a collection of object the first argument is can be a property key or getter function receiving the object.
import { Collection } from '@upfrontjs/framework';
const collection = new Collection([1, 2]);
collection.join('-'); // '1-2'
const objectCollection = new Collection([{ id: 1 }, { id: 2 }]);
objectCollection.join('id', '-'); // '1-2'
objectCollection.join(obj => obj.id + 1); // '2,3'
sum
The sum method returns the summative the collection numbers while casting strings to numbers if possible otherwise throws an error. Optionally it takes a string for the property key or getter function receiving the item to return a single value.
import { Collection } from '@upfrontjs/framework';
let collection = new Collection([1, 2]);
collection.sum(); // 3
collection = new Collection(['3', '4']);
collection.sum(); // 7
collection = new Collection([{ id: 1 }, { id: 2 }]);
collection.sum('id'); // 3
collection.sum(obj => obj.id); // 3
min
The min method returns the lowest number from the collection while casting strings to numbers if possible otherwise throws an error. Optionally it takes a string for the property key or getter function receiving the item to return a single value.
import { Collection } from '@upfrontjs/framework';
let collection = new Collection([1, 2]);
collection.min(); // 1
collection = new Collection(['3', '4']);
collection.min(); // 3
collection = new Collection([{ id: 1 }, { id: 2 }]);
collection.min('id'); // 1
collection.min(obj => obj.id); // 1
max
The max method returns the highest number from the collection while casting strings to numbers if possible otherwise throws an error. Optionally it takes a string for the property key or getter function receiving the item to return a single value.
import { Collection } from '@upfrontjs/framework';
let collection = new Collection([1, 2]);
collection.max(); // 2
collection = new Collection(['3', '4']);
collection.max(); // 4
collection = new Collection([{ id: 1 }, { id: 2 }]);
collection.max('id'); // 2
collection.max(obj => obj.id); // 2
average
The average method returns the average of the number from the collection while casting strings to numbers if possible otherwise throws an error. Optionally it takes a string for the property key or getter function receiving the item to return a single value.
import { Collection } from '@upfrontjs/framework';
let collection = new Collection([1, 2]);
collection.average(); // 1.5
collection = new Collection(['3', '4']);
collection.average(); // 3.5
collection = new Collection([{ id: 1 }, { id: 2 }]);
collection.average('id'); // 1.5
collection.average(obj => obj.id); // 1.5