Tracks
/
Crystal
Crystal
/
Exercises
/
Language List
Language List

Language List

Learning Exercise

Introduction

Array is a mutable data structure that stores a collection of elements of a specific type. An array is an indexable data structure. Arrays being mutable means that if a method is called on an array that modifies the array, the array will be modified. Meaning it doesn't create a new array but modifies the existing one.

To create an array, use the array literal denotation syntax ([]) and within it, specify the elements of the array separated by a comma.

[1, 2, 3] # => [1, 2, 3]

Crystal will infer the type of the array from the elements.

[1, 2, 3].class # => Array(Int32)

Multi-type Arrays

Even if mentioned earlier about arrays being a collection of elements of a specific type, you can create an array with multiple types using union types. This allows the array to contain elements of any of the types specified in the union type. Crystal will infer the type of the array from the elements.

[1, "2", 3.0] # => [1, "2", 3.0]

[1, "2", 3.0].class # => Array(Int32 | Float64 | String)

Multi-dimensional arrays

A multi-dimensional array is an array of arrays. This means that each element in the array is an array itself. This can be useful when wanting to store data in a table format. To define a multi-dimensional array, you can either write an array of arrays literal or use the Array.new constructor.

[[1, 2], [3, 4]]                    # => [[1, 2], [3, 4]]
numbers = Array(Array(Int32)).new() # => []
numbers << [1, 2]                   # => [[1, 2]]

Add an element to an array

To add an element to an array, use the << (append) operator.

[1, 2, 3] << 4 # => [1, 2, 3, 4]

The type of the element you want to add must be the same as the type of the array, if it is not an error will be raised.

numbers : Array(Int32 | Float64) = [1, 2, 3]
numbers << 4.0
numbers # => [1, 2, 3, 4.0]

numbers << "5" # => Error: no overload matches 'Array(Int32 | Float64)#<<' with type String

Size of an Array

As with String, can you get the size of an array by using the size method.

[1, 2, 3].size # => 3

Empty Arrays

The compiler cannot infer the array type when creating an empty array. Therefore, you need to specify the type of the array. This can be done by specifying the array's type, using the of keyword, or using the array initializer syntax, which is Array(T).new.

[] of (Int32 | Float64 | String)    # => []
Array(Int32 | Float64 | String).new # => []

Accessing Elements

As with String, you can access elements in an array by using the [] (index) operator and giving it the index of the element you want to access. If the index is out of bounds, an IndexError will be raised.

[1, 2, 3][0] # => 1

[1, 2, 3][3] # => Index out of bounds (IndexError)

It is also possible to access elements by using a range.

[1, 2, 3][0..1] # => [1, 2]

Create an array from a range

To create an array from a range, use the to_a method. This can be useful when you want to create an array of numbers.

(1..3).to_a # => [1, 2, 3]

Create an array from a string

To create an array from a string, use the split method. This lets you split a string into an array of strings using a delimiter.

"1,2,3".split(",") # => ["1", "2", "3"]

It is also possible to get an array of characters from a string using the chars method.

"123".chars # => ['1', '2', '3']

To convert an array of Char or String to a String you can use the join method which takes a delimiter as an argument.

['1', '2', '3'].join(".") # => "1.2.3"

Deleting element from an array

When you want to delete an element from the end of an array, you can use the pop method, which takes an optional argument specifying how many elements to remove from the end of the array. The method returns the element that was removed. If the array is empty an IndexError will be raised.

numbers = [1, 2, 3]
[1, 2, 3].pop # => 3
numbers       # => [1, 2]

empty_numbers = [] of Int32
empty_numbers.pop # => Index out of bounds (IndexError)

When you want to delete an element of a specific index from an array, you can use the delete_at method which takes the element's index to remove as an argument. If the array is empty an IndexError will be raised.

numbers = [1, 2, 3]
[1, 2, 3].delete_at(1) # => 2
numbers                # => [1, 3]

empty_numbers = [] of Int32
empty_numbers.delete_at(0) # => Index out of bounds (IndexError)

Modifying values in an array

When you want to modify an element of a specific index from an array, you can use the []= (index assign) operator which takes the index of the element to modify and the new value as arguments. If the index is out of bounds, an IndexError will be raised.

numbers = [1, 2, 3]
numbers[1] = 4
numbers # => [1, 4, 3]

numbers[3] = 5 # => Index out of bounds (IndexError)

Instructions

In this exercise you need to implement some methods to manipulate an array of programming languages.

1. Define a method to return an empty language array

Define the LanguageList.list method that takes no arguments and returns an empty array of the type Array(String).

LanguageList.list()
# => []

2. Define a method to add a language to the array

Define the LanguageList.add method that takes 2 arguments (a language array and a string literal of a language). The method should return the array with the new language added to the end of the array.

language_list = LanguageList.list()
# => []
language_list = LanguageList.add(language_list, "Crystal")
# => ["Crystal"]
language_list = LanguageList.add(language_list, "Ruby")
# => ["Crystal", "Ruby"]

3. Define a method to remove a language from the array

Define the LanguageList.remove method that takes 1 argument (a language array). The method should return the array without the last item. Assume the array will always have at least one item.

language_list = LanguageList.list()
# => []
language_list = LanguageList.add(language_list, "Crystal")
# => ["Crystal"]
language_list = LanguageList.add(language_list, "Ruby")
# => ["Crystal", "Ruby"]
language_list = LanguageList.remove(language_list)
# => ["Crystal"]

4. Define a method to return the nth item in the array

Define the LanguageList.at function that takes 2 argument (a language array and an index). The method should return the language at n index in the array. Assume that on the index will there always be a language.

language_list = LanguageList.new()
# => []
language_list = LanguageList.add(language_list, "Crystal")
# => ["Crystal"]
language_list = LanguageList.add(language_list, "Ruby")
# => ["Crystal", "Ruby"]
LanguageList.at(language_list, 1)
# => "Ruby"

5. Define a method to parse a string of languages

Define the LanguageList.parse method that takes 1 argument (a string literal of languages separated by a comma). The method should return an array of languages.

LanguageList.parse("Crystal, Ruby")
# => ["Crystal", "Ruby"]
Edit via GitHub The link opens in a new window or tab
Crystal Exercism

Ready to start Language List?

Sign up to Exercism to learn and master Crystal with 26 concepts, 133 exercises, and real human mentoring, all for free.