Collections
A collection holds many values under one name. MaSH has two basic kinds, arrays and dictionaries, and a toolkit called mash.collect for working on them.
Arrays
Section titled “Arrays”An array is an ordered list in square brackets:
set colours to ["red", "green", "blue"]printline colours[0]printline colours[2]printline count(colours)redblue3colours = ["red", "green", "blue"]printline(colours[0])printline(colours[2])printline(count(colours))redblue3Positions start at 0, so the first item is colours[0]. count() tells you how many items there are. (Arrays have no .length.)
Change an item by its position, and add one to the end with []:
set colours to ["red", "green"]set colours[0] to "pink"colours[] = "blue"printline coloursArray [ "pink", "green", "blue"]colours = ["red", "green"]colours[0] = "pink"colours[] = "blue"printline(colours)Array [ "pink", "green", "blue"]Arrays can hold anything, including other arrays:
set grid to [[1, 2], [3, 4]]printline grid[1][0]3grid = [[1, 2], [3, 4]]printline(grid[1][0])3Dictionaries
Section titled “Dictionaries”A dictionary stores values under names, called keys. Use curly braces:
set person to {name: "Ada", age: 36}printline person["name"]printline person.ageAda36person = {name: "Ada", age: 36}printline(person["name"])printline(person.age)Ada36Read a value with ["key"] or with a dot. Add or change one the same way:
set person to {name: "Ada"}set person["age"] to 36set person.city to "London"printline personDictionary { "name": "Ada", "age": 36, "city": "London"}person = {name: "Ada"}person["age"] = 36person.city = "London"printline(person)Dictionary { "name": "Ada", "age": 36, "city": "London"}Reading a key that isn’t there gives null, not an error. That makes ?? a good fit:
set person to {name: "Ada"}printline person["phone"] ?? "no phone on file"no phone on fileperson = {name: "Ada"}printline(person["phone"] ?? "no phone on file")no phone on fileDictionaries can nest, and an array can hold dictionaries. This is the shape of most data you’ll get from files and web services:
set orders to [ {ref: "A-1", total: 40}, {ref: "A-2", total: 15}]each orders as order printline "{{order.ref}}: {{order.total}}"endA-1: 40A-2: 15orders = [ {ref: "A-1", total: 40}, {ref: "A-2", total: 15}]each (orders) as order { printline("{{order.ref}}: {{order.total}}")}A-1: 40A-2: 15mash.collect
Section titled “mash.collect”Wrap an array or dictionary in mash.collect() and you get a Collection with lots of helper methods. Many of them take a block of script, which is a small piece of code run once per item. You’ll write blocks properly in Blocks. For now, copy the shape.
Totals and joins
Section titled “Totals and joins”set prices to mash.collect([12, 30, 8])printline prices.sum()printline prices.max()printline prices.min()printline prices.avg()printline prices.count()printline prices.join(", ")5030816.666666666667312, 30, 8prices = mash.collect([12, 30, 8])printline(prices.sum())printline(prices.max())printline(prices.min())printline(prices.avg())printline(prices.count())printline(prices.join(", "))5030816.666666666667312, 30, 8Filtering
Section titled “Filtering”filter keeps the items for which the block returns true:
set people to mash.collect([ {name: "Ada", age: 36}, {name: "Bo", age: 17}, {name: "Cy", age: 52}])set adults to people.filter(block person return person["age"] is more than or equal to 18end)printline adults.count()printline adults.pluck("name").join(" and ")2Ada and Cypeople = mash.collect([ {name: "Ada", age: 36}, {name: "Bo", age: 17}, {name: "Cy", age: 52}])adults = people.filter(block(person) { return person["age"] >= 18})printline(adults.count())printline(adults.pluck("name").join(" and "))2Ada and Cypluck pulls one key out of every item. sum("age") adds up one key. where is a shortcut for simple matches:
set people to mash.collect([ {name: "Ada", team: "x", age: 36}, {name: "Bo", team: "y", age: 17}, {name: "Cy", team: "x", age: 52}])printline people.sum("age")printline people.where("team", "x").count()printline people.sortBy("age").first()["name"]printline people.sortByDesc("age").first()["name"]1052BoCypeople = mash.collect([ {name: "Ada", team: "x", age: 36}, {name: "Bo", team: "y", age: 17}, {name: "Cy", team: "x", age: 52}])printline(people.sum("age"))printline(people.where("team", "x").count())printline(people.sortBy("age").first()["name"])printline(people.sortByDesc("age").first()["name"])1052BoCyChanging every item
Section titled “Changing every item”map builds a new collection from the results of a block:
set names to mash.collect(["ada", "bo"])set shouted to names.map(block n return mash.str(n).upper().toString()end)printline shouted.join(", ")ADA, BOnames = mash.collect(["ada", "bo"])shouted = names.map(block(n) { return mash.str(n).upper().toString()})printline(shouted.join(", "))ADA, BOSorting
Section titled “Sorting”set n to mash.collect([5, 2, 8])printline n.sort().values().join(", ")printline n.sortDesc().values().join(", ")2, 5, 88, 5, 2n = mash.collect([5, 2, 8])printline(n.sort().values().join(", "))printline(n.sortDesc().values().join(", "))2, 5, 88, 5, 2A sorted collection remembers where each item used to sit. Add .values() before you print or join so the order is tidy.
Looping over a collection
Section titled “Looping over a collection”A collection works in each just like an array:
set people to mash.collect([{name: "Ada"}, {name: "Bo"}])each people as person printline person["name"]endAdaBopeople = mash.collect([{name: "Ada"}, {name: "Bo"}])each (people) as person { printline(person["name"])}AdaBoMany of the things MaSH gives back, such as a list of files, are collections. You can filter, sort and total them with the methods above.
A plain dictionary takes the same methods. person.has("name") and person.keys() work, and person.remove("name") changes person itself.
set person to {name: "Ada", role: "admin"}printline person.has("name")person.remove("role")printline person.keys()trueArray [ "name"]person = {name: "Ada", role: "admin"}printline(person.has("name"))person.remove("role")printline(person.keys())trueArray [ "name"]Try it
Section titled “Try it”Make an array of five numbers. Print the total, the biggest, and a list of only the ones above 10.
Next, you’ll learn to write your own reusable pieces.