Anytime your results return multiple values then an instance of Collection
is returned. This allows you to iterate over your values and has a lot of shorthand methods.
When using collections as a query result you can iterate over it as if the collection with a normal list:
Copy users = User.get() #== <masoniteorm.collections.Collection>
users.count() #== 50
users.pluck('email') #== <masoniteorm.collections.Collection> of emails
for user in users:
user.email #== 'joe@masoniteproject.com'
Available Methods
Here is the updated list with min
added after merge
:
all
Returns the underlying list or dict represented by the collection:
Copy users = User.get().all() #== [<app.User.User>, <app.User.User>]
Collection([1, 2, 3]).all() #== [1, 2, 3]
avg
Returns the average of all items in the collection:
Copy Collection([1, 2, 3, 4, 5]).avg() #== 3
If the collection contains nested objects or dictionaries (e.g. for a collection of models), you must pass a key to use for determining which values to calculate the average:
Copy average_price = Product.get().avg('price')
chunk
Chunks a collection into multiple, smaller collections of a given size. Uses a generator to keep each chunk small. Useful for chunking large data sets where pulling too many results in memory will overload the application.
Copy collection = Collection([1, 2, 3, 4, 5, 6, 7])
chunks = collection.chunk(2).serialize() #== [[1, 2], [3, 4], [5, 6], [7]]
collapse
Collapses a collection of lists into a flat collection:
Copy collection = Collection([[1, 2, 3], [4, 5, 6])
collection.collapse().serialize() #== [1, 2, 3, 4, 5, 6]
contains
Determines whether the collection contains a given item:
Copy collection = Collection(['foo', 'bar'])
collection.contains('foo') #== True
You can also pass a key / value pair to the contains method, which will determine if the given pair exists in the collection.
Finally, you may also pass a callback to the contains method to perform your own truth test:
Copy collection = Collection([1, 2, 3, 4, 5])
collection.contains(lambda item: item > 5) #== False
count
Returns the total number of items in the collection. len()
standard python method can also be used.
diff
Returns the difference as a collection against another collection
Copy collection = Collection([1, 2, 3, 4, 5])
diff = collection.diff([2, 4, 6, 8])
diff.all() #== [1, 3, 5]
each
Iterates over the items in the collection and passes each item to a given callback:
Copy posts.each(lambda post: post.author().save(author))
every
Creates a new collection by applying a given callback on every element:
Copy collection = Collection([1, 2, 3])
collection.every(lambda x: x*2 ).all() #== [2, 4, 6]
filter
Filters the collection by a given callback, keeping only those items that pass a given truth test:
Copy collection = Collection([1, 2, 3, 4])
filtered = collection.filter(lambda item: item > 2)
filtered.all() #== [3, 4]
first
Returns the first item of the collection, if no arguments are given.
When given a truth test as callback, it returns the first element in the collection that passes the test:
Copy collection = Collection([1, 2, 3, 4])
collection.first(lambda item: item > 2)
flatten
Flattens a multi-dimensional collection into a single dimension:
Copy collection = Collection([1, 2, [3, 4, 5, {'foo': 'bar'}]])
flattened = collection.flatten().all() #== [1, 2, 3, 4, 5, 'bar']
forget
Removes an item from the collection by its key:
Copy collection = Collection([1, 2, 3, 4, 5])
collection.forget(1).all() #== [1,3,4,5]
collection.forget(0,2).all() #== [3,5]
Unlike most other collection methods, forget
does not return a new modified collection; it modifies the collection it is called on.
for_page
Paginates the collection by returning a new collection containing the items that would be present on a given page number:
Copy collection = Collection([1, 2, 3, 4, 5, 6, 7, 8, 9])
chunk = collection.for_page(2, 4).all() #== 4, 5, 6, 7
for_page(page, count)
takes the page number and the number of items to show per page.
get
Returns the item at a given key or index. If the key does not exist, None is returned. An optional default value can be passed as the second argument:
Copy collection = Collection([1, 2, 3])
collection.get(0) #== 1
collection.get(4) #== None
collection.get(4, 'default') #== 'default'
collection = Collection({"apples": 1, "cherries": 2})
collection.get("apples") #== 1
group_by
Returns a collection where items are grouped by the given key:
Copy collection = Collection([
{"id": 1, "type": "a"},
{"id": 2, "type": "b"},
{"id": 3, "type": "a"}
])
collection.implode("type").all()
#== {'a': [{'id': 1, 'type': 'a'}, {'id': 4, 'type': 'a'}],
# 'b': [{'id': 2, 'type': 'b'}]}
implode
Joins the items in a collection with ,
or the given glue string.
Copy collection = Collection(['foo', 'bar', 'baz'])
collection.implode() #== foo,bar,baz
collection.implode('-') #== foo-bar-baz
If the collection contains dictionaries or objects, you must pass the key of the attributes you wish to join:
Copy collection = Collection([
{'account_id': 1, 'product': 'Desk'},
{'account_id': 2, 'product': 'Chair'}
])
collection.implode(key='product') #== Desk,Chair
collection.implode(" - ", key='product') #== Desk - Chair
is_empty
Returns True
if the collection is empty; otherwise, False
is returned:
Copy Collection([]).is_empty() #== True
last
Returns the last element in the collection if no arguments are given.
Returns the last element in the collection that passes the given truth test:
Copy collection = Collection([1, 2, 3, 4])
last = collection.last(lambda item: item < 3) #== 2
map
Iterates through the collection and passes each value to the given callback. The callback is free to modify the item and return it, thus forming a new collection of modified items:
Copy collection = Collection([1, 2, 3, 4])
multiplied = collection.map(lambda item: item * 2).all() #== [2, 4, 6, 8]
map_into
Iterates through the collection and cast each value into the given class:
Copy collection = Collection([1,2])
collection.map_into(str).all() #== ["1", "2"]
A class method can also be specified. Some additional keywords arguments can be passed to this method:
Copy class Point:
@classmethod
def as_dict(cls, coords, one_dim=False):
if one_dim:
return {"X": coords[0]}
return {"X": coords[0], "Y": coords[1]}
collection = Collection([(1,2), (3,4)])
collection.map_into(Point, "as_dict") #== [{'X': 1, 'Y': 2}, {'X': 3, 'Y': 4}]
collection.map_into(Point, "as_dict", one_dim=True) #== [{'X': 1}, {'X': 3}]
max
Retrieves max value of the collection:
Copy collection = Collection([1,2,3])
collection.max() #== 3
If the collection contains dictionaries or objects, you must pass the key on which to compute max value:
Copy collection = Collection([
{'product_id': 1, 'product': 'Desk'},
{'product_id': 2, 'product': 'Chair'}
{'product_id': 3, 'product': 'Table'}
])
collection.max("product_id") #== 3
merge
Merges the given list into the collection:
Copy collection = Collection(['Desk', 'Chair'])
collection.merge(['Bookcase', 'Door'])
collection.all() #== ['Desk', 'Chair', 'Bookcase', 'Door']
Unlike most other collection methods, merge
does not return a new modified collection; it modifies the collection it is called on.
min
Retrieves min value of the collection:
Copy collection = Collection([1,2,3])
collection.min() #== 1
If the collection contains dictionaries or objects, you must pass the key on which to compute min value:
Copy collection = Collection([
{'product_id': 1, 'product': 'Desk'},
{'product_id': 2, 'product': 'Chair'}
{'product_id': 3, 'product': 'Table'}
])
collection.max("product_id") #== 1
pluck
Retrieves all of the collection values for a given key:
Copy collection = Collection([
{'product_id': 1, 'product': 'Desk'},
{'product_id': 2, 'product': 'Chair'}
{'product_id': 3, 'product': None}
])
plucked = collection.pluck('product').all() #== ['Desk', 'Chair', None]
A key can be given to pluck the collection into a dictionary with the given key
Copy collection.pluck("product", "product_id") #== {1: 'Desk', 2: 'Chair', 3: None}
You can pass keep_nulls=False
to remove None
value in the collection.
Copy collection.pluck("product", keep_nulls=False) #== ['Desk', 'Chair']
pop
Removes and returns the last item from the collection:
Copy collection = Collection([1, 2, 3, 4, 5])
collection.pop() #== 5
collection.all() #== [1, 2, 3, 4]
prepend
Adds an item to the beginning of the collection:
Copy collection = Collection([1, 2, 3, 4])
collection.prepend(0)
collection.all() #== [0, 1, 2, 3, 4]
pull
Removes and returns an item from the collection by its key:
Copy collection = Collection([1, 2, 3, 4])
collection.pull(1) #== 2
collection.all() #== [1, 3, 4]
collection = Collection({'apple': 1, 'cherry': 3, 'lemon': 2})
collection.pull('cherry') #== 3
collection.all() #== {'apple': 1, 'lemon': 2}
push
Appends an item to the end of the collection:
put
Sets the given key and value in the collection:
Copy collection = Collection([1, 2, 3, 4])
collection.put(1, 5)
collection.all() #== [1, 5, 3, 4]
collection = Collection({'apple': 1, 'cherry': 3, 'lemon': 2})
collection.put('cherry', 0)
collection.all() #== {'apple': 1, 'cherry': 0, 'lemon': 2}
random
Returns a random item from the collection
Copy user = User.all().random() #== returns a random User instance
An integer count can be given to random
method to specify how many items you would like to randomly retrieve from the collection. A collection will always be returned when the items count is specified
Copy users = User.all().random(3) #== returns a Collection of 3 users
users.count() #== 3
users.all() #== returns a list of 3 users
If the collection length is smaller than specified count a ValueError
will be raised.
reduce
Reduces the collection to a single value, passing the result of each iteration into the subsequent iteration.
Copy collection = Collection([1, 2, 3])
collection.reduce(lambda result, item: (result or 0) + item) #== 6
Initial value is 0
by default but can be overridden:
Copy collection.reduce(lambda result, item: (result or 0) + item, 4) #== 10
reject
Copy collection = Collection([1, 2, 3, 4])
filtered = collection.reject(lambda item: item > 2)
filtered.all() #== [1, 2]
Unlike most other collection methods, reject
does not return a new modified collection; it modifies the collection it is called on.
reverse
Reverses the order of the items in the collection:
Copy collection = Collection([1, 2, 3])
collection.reverse().all() #== [3, 2, 1]
Unlike most other collection methods, reverse
does not return a new modified collection; it modifies the collection it is called on.
serialize
Copy collection = Collection([1, 2, 3])
collection.serialize() #== [1, 2, 3]
collection = Collection([User.find(1)])
collection.serialize() #== [{'id': 1, 'name': 'John', 'email': 'john.doe@masonite.com'}]
shift
Removes and returns the first item from the collection:
Copy collection = Collection([1, 2, 3, 4, 5])
collection.shift() #== 1
collection.all() #== [2, 3, 4, 5]
sort
Sorts the collection:
Copy collection = Collection([5, 3, 1, 2, 4])
sorted = collection.sort()
sorted.all() #== [1, 2, 3, 4, 5]
sum
Returns the sum of all items in the collection:
Copy Collection([1, 2, 3, 4, 5]).sum() #== 15
If the collection contains dictionaries or objects, you must pass a key to use for determining which values to sum:
Copy collection = Collection([
{'name': 'JavaScript: The Good Parts', 'pages': 176},
{'name': 'JavaScript: The Defnitive Guide', 'pages': 1096}
])
collection.sum('pages') #== 1272
take
Returns a new collection with the specified number of items:
Copy collection = Collection([0, 1, 2, 3, 4, 5])
chunk = collection.take(3)
chunk.all() #== [0, 1, 2]
You can also pass a negative integer to take the specified amount of items from the end of the collection:
Copy chunk = collection.chunk(-2)
chunk.all() #== [4, 5]
to_json
Converts the collection into JSON:
Copy collection = Collection([{'name': 'Desk', 'price': 200}])
collection.to_json() #== '[{"name": "Desk", "price": 200}]'
Iterates over the collection and calls the given callback with each item in the collection. The items in the collection will be replaced by the values returned by the callback:
Copy collection = Collection([1, 2, 3, 4, 5])
collection.transform(lambda item: item * 2)
collection.all() #== [2, 4, 6, 8, 10]
unique
Returns all of the unique items in the collection:
Copy collection = Collection([1, 1, 2, 2, 3, 4, 2])
unique = collection.unique()
unique.all() #== [1, 2, 3, 4]
When dealing with dictionaries or objects, you can specify the key used to determine uniqueness:
Copy collection = Collection([
{'name': 'Sam', 'role': 'admin'},
{'name': 'Joe', 'role': 'basic'},
{'name': 'Joe', 'role': 'admin'},
])
unique = collection.unique('name')
unique.all()
# [
# {'name': 'Sam', 'role': 'admin'},
# {'name': 'Joe', 'role': 'basic'}
# ]
where
Filters the collection by a given key / value pair:
Copy collection = Collection([
{'name': 'Desk', 'price': 200},
{'name': 'Chair', 'price': 100},
{'name': 'Bookcase', 'price': 150},
{'name': 'Door', 'price': 100},
])
filtered = collection.where('price', 100)
filtered.all()
# [
# {'name': 'Chair', 'price': 100},
# {'name': 'Door', 'price': 100}
# ]
zip
Merges together the values of the given list with the values of the collection at the corresponding index:
Copy collection = Collection(['Chair', 'Desk'])
zipped = collection.zip([100, 200])
zipped.all() #== [('Chair', 100), ('Desk', 200)]