Collections

© 2017 Morgan C. Benton code4your.life

Collection

A group of things that are somehow related to one another and can be referred to using a common group label, e.g. a necktie collection

© 2017 Morgan C. Benton code4your.life

Without Collections

With Collections

// declare some numeric variables
let datum0 = 17.3523;
let datum1 = 26.0174;
let datum2 = 94.2684;
let datum3 = 76.9841;
let datum4 = 85.2911;

// calculate the average of the variables
let avg = (datum0 + datum1 + datum2 + datum3 + datum4) / 5;
// create a collection of numbers
let data = [17.3523, 26.0174, 94.2684, 76.9841, 85.2911];

// calculate the average of the numbers
let avg = 0;
for (let i = 0; i < data.length; i += 1) {
    avg += data[i] / data.length;
}

© 2017 Morgan C. Benton code4your.life

Elements

  • Each member of the group is called an "element"
  • Elements can be
    • Homogeneous: all the same kind of thing
    • Heterogeneous: different kinds of things

© 2017 Morgan C. Benton code4your.life

INdices

  • Each element has a label called an "index"
  • Indices can be
    • Integers (better for homogeneous collections)
    • String (better for heterogeneous collections)

© 2017 Morgan C. Benton code4your.life

INteger Indices

Integer indices (usually) start from zero:

data 17.3523 26.0174 94.2684 76.9841 85.2911
index [0] [1] [2] [3] [4]
// create a collection of numbers
let data = [17.3523, 26.0174, 94.2684, 76.9841, 85.2911];

// output the third element in the collection (where index = 2)
console.log(data[2]); // outputs 94.2684

© 2017 Morgan C. Benton code4your.life

String Indices (Keys)

  • Used mostly for heterogeneous collections
  • Elements are a collection of key/value pairs
  • Keys describe the content of the element value
  • A collection of key/value pairs is sometimes called a "hash table"
// a "student" is a collection of properties (key/value pairs)
// grouping related information about a real-world object
let student = {
    "first_name": "Cynthia",
    "last_name": "Morales",
    "dob": 1986-07-22,
    "email": "cynthia.morales@example.com"
};

// example of accessing one of the elements
console.log(student["last_name"]); // outputs Morales

© 2017 Morgan C. Benton code4your.life

Arrays

  • Usually homogeneous
  • Integer indices
  • Exist in nearly every programming language
  • Can be multi-dimensional

Non-Arrays

  • Usually heterogeneous
  • String indices
  • Called different things in different languages, e.g.
    • Object
    • Hash table
    • Associative array
    • List
    • Struct

Collection Types

© 2017 Morgan C. Benton code4your.life

Common Array
Properties & Operations

  • length -- integer representing number of elements   
  • [index] -- access the element at index

  • push(el) -- adds an element to the end
  • pop() -- removes last element and returns it
  • unshift(el) -- adds an element to the beginning
  • shift() -- removes first element and returns it
  • reverse() -- reverses the order of the elements
  • sort() -- sort elements according to specified criteria
  • concat() -- join two or more arrays together
  • indexOf(el) -- searches array for el and returns index

© 2017 Morgan C. Benton code4your.life

More Common Array
Operations

  • filter(func) -- filter using a boolean function
  • each(func) -- modify each element using the function
  • map(func) -- convert to a new array using the function
  • reduce(func) -- reduce all to a single aggregate value

© 2017 Morgan C. Benton code4your.life

Code Examples

Showing usage of many/most of the common properties and operations of arrays in:
JavaScript, Python, R, Ruby, PHP, Java, and Go

© 2017 Morgan C. Benton code4your.life

JavaScript

let fruit = [];                     // create a new, empty array
let fruit = [ 'banana', 'apple', 'pear' ]; // or initialize with data
fruit.push('grape');                // [ 'banana', 'apple', 'pear', 'grape' ]
fruit.unshift('orange');            // [ 'orange', 'banana', 'apple', 'pear', 'grape' ]
console.log(fruit.length);          // 5
console.log(fruit[2]);              // apple
let last = fruit.pop();             // [ 'orange', 'banana', 'apple', 'pear' ]
console.log(last);                  // grape
let first = fruit.shift();          // [ 'banana', 'apple', 'pear' ]
console.log(first);                 // orange
fruit.reverse();                    // [ 'pear', 'apple', 'banana' ]
fruit = fruit.concat(['pear', 'grape']); // [ 'pear', 'apple', 'banana', 'pear', 'grape' ]
let b = fruit.indexOf('banana');    // b = 2
fruit.splice(b, 1);                 // [ 'pear', 'apple', 'pear', 'grape' ]
fruit.splice(b, 0, 'banana');       // [ 'pear', 'apple', 'banana', 'pear', 'grape' ]
console.log(fruit.join(", "));      // pear, apple, banana, pear, grape
let pear2 = fruit.lastIndexOf('pear'); // pear2 = 3
fruit.splice(pear2, 1);             // [ 'pear', 'apple', 'banana', 'grape' ]
fruit.sort();                       // [ 'apple', 'banana', 'grape', 'pear' ]
fruit = fruit.map(f => f.toUpperCase()); // [ 'APPLE', 'BANANA', 'GRAPE', 'PEAR' ]
fruit.forEach((f, i, frt) => { 
  frt[i] = f.toLowerCase();
});                                 // [ 'apple', 'banana', 'grape', 'pear' ]

© 2017 Morgan C. Benton code4your.life

Python

fruit = []                            # create a new, empty array
fruit = [ 'banana', 'apple', 'pear' ] # or initialize with data
fruit.append('grape')                 # [ 'banana', 'apple', 'pear', 'grape' ]
fruit.insert(0, 'orange')             # [ 'orange', 'banana', 'apple', 'pear', 'grape' ]
print(len(fruit))                     # 5
print(fruit[2])                       # apple
last = fruit.pop()                    # [ 'orange', 'banana', 'apple', 'pear' ]
print(last)                           # grape
first = fruit.pop(0)                  # [ 'banana', 'apple', 'pear' ]
print(first)                          # orange
fruit.reverse()                       # [ 'pear', 'apple', 'banana' ]
fruit.extend(['pear', 'grape' ])      # [ 'pear', 'apple', 'banana', 'pear', 'grape' ]
b = fruit.index('banana')             # b = 2
fruit.pop(b)                          # [ 'pear', 'apple', 'pear', 'grape' ]
fruit.insert(b, 'banana')             # [ 'pear', 'apple', 'banana', 'pear', 'grape' ]
print(", ".join(fruit))               # pear, apple, banana, pear, grape
p2 = len(fruit) - 1 - fruit[::-1].index('pear') # p2 = 3
fruit.pop(p2)                         # [ 'pear', 'apple', 'banana', 'grape' ]
fruit.sort()                          # [ 'apple', 'banana', 'grape', 'pear' ]
fruit = list(map(lambda f: f.upper(), fruit)) # [ 'APPLE', 'BANANA', 'GRAPE', 'PEAR' ]
fruit = [f.lower() for f in fruit]    # [ 'apple', 'banana', 'grape', 'pear' ]

© 2017 Morgan C. Benton code4your.life

R

fruit <- 0                                  # create a new, empty data structure
fruit <- c('banana', 'apple', 'pear')       # or initialize with data
fruit <- c(fruit, 'grape')                  # ['banana', 'apple', 'pear', 'grape']
fruit <- c('orange', fruit)                 # ['orange', 'banana', 'apple', 'pear', 'grape']
print(length(fruit))                        # 5
print(fruit[3])                             # apple -- NOTE: indices start at 1, NOT 0
print(fruit[length(fruit)])                 # grape
fruit <- fruit[1:length(fruit) - 1]         # ['orange', 'banana', 'apple', 'pear']
print(fruit[1])                             # orange
fruit <- fruit[-1]                          # ['banana', 'apple', 'pear']
fruit <- rev(fruit)                         # ['pear', 'apple', 'banana']
fruit <- c(fruit, c('pear', 'grape'))       # ['pear', 'apple', 'banana', 'pear', 'grape']
b <- match('banana', fruit)                 # b <- 3
fruit <- fruit[-b]                          # ['pear', 'apple', 'pear', 'grape']
fruit <- append(fruit, 'banana', after=b-1) # ['pear', 'apple', 'banana', 'pear', 'grape']
print(paste(fruite, collapse=", "))         # pear, apple, banana, pear, grape
pear2 <- which(fruit=='pear')[-1]           # pear2 <- 4
fruit <- fruit[-pear2]                      # ['pear', 'apple', 'banana', 'grape']
fruit <- sort(fruit)                        # ['apple', 'banana', 'grape', 'pear']
fruit <- toupper(fruit)                     # ['APPLE', 'BANANA', 'GRAPE', 'PEAR']
fruit <- tolower(fruit)                     # ['apple', 'banana', 'grape', 'pear']

© 2017 Morgan C. Benton code4your.life

Ruby

fruit = []                            # create a new, empty array
fruit = [ 'banana', 'apple', 'pear' ] # or initialize with data
fruit.push('grape')                   # [ 'banana', 'apple', 'pear', 'grape' ]
fruit.unshift('orange')               # [ 'orange', 'banana', 'apple', 'pear', 'grape' ]
puts(fruit.length)                    # 5
puts(fruit[2])                        # apple
last = fruit.pop                      # [ 'orange', 'banana', 'apple', 'pear' ]
puts(last)                            # grape
first = fruit.shift                   # [ 'banana', 'apple', 'pear' ]
puts(first)                           # orange
fruit.reverse!                        # [ 'pear', 'apple', 'banana' ]
fruit.concat(['pear', 'grape' ])      # [ 'pear', 'apple', 'banana', 'pear', 'grape' ]
b = fruit.find_index('banana')        # b = 2
fruit.delete_at(b)                    # [ 'pear', 'apple', 'pear', 'grape' ]
fruit.insert(b, 'banana')             # [ 'pear', 'apple', 'banana', 'pear', 'grape' ]
puts(fruit.join(", "))                # pear, apple, banana, pear, grape
pear2 = fruit.rindex('pear')          # pear2 = 3
fruit.delete_at(pear2)                # [ 'pear', 'apple', 'banana', 'grape' ]
fruit.sort!                           # [ 'apple', 'banana', 'grape', 'pear' ]
fruit.map!{|f| f.upcase}              # [ 'APPLE', 'BANANA', 'GRAPE', 'PEAR' ]
fruit.each_with_index{|f,i| fruit[i] = f.downcase} # [ 'apple', 'banana', 'grape', 'pear' ]

© 2017 Morgan C. Benton code4your.life

PHP

$fruit = [];                          // create a new, empty array
$fruit = ['banana','apple', 'pear'];  // or initialize with data
$fruit[] = 'grape';                   // push(): [ 'banana', 'apple', 'pear', 'grape' ]
array_unshift($fruit, 'orange');      // [ 'orange', 'banana', 'apple', 'pear', 'grape' ]
echo count($fruit);                   // length(): 5
echo $fruit[2];                       // apple
$last = array_pop($fruit);            // [ 'orange', 'banana', 'apple', 'pear' ]
echo $last;                           // grape
$first = array_shift($fruit);         // [ 'banana', 'apple', 'pear' ]
echo $first;                          // orange
$fruit = array_reverse($fruit);       // [ 'pear', 'apple', 'banana' ]
$new = ['pear', 'grape'];
$fruit = array_merge($fruit, $new);   // [ 'pear', 'apple', 'banana', 'pear', 'grape' ]
$b = array_search('banana', $fruit);  // indexOf(): $b = 2
array_splice($fruit, $b, 1);          // [ 'pear', 'apple', 'pear', 'grape' ]
array_splice($fruit, $b, 0, 'banana');// [ 'pear', 'apple', 'banana', 'pear', 'grape' ]
echo implode(", ", $fruit);           // join(): pear, apple, banana, pear, grape
$pears = array_keys($fruit, 'pear');  // [ 0, 3 ]
$p2 = array_pop($pears);              // lastIndexOf(): $p2 = 3
array_splice($fruit, $p2, 1);         // [ 'pear', 'apple', 'banana', 'grape' ]
sort($fruit);                         // [ 'apple', 'banana', 'grape', 'pear' ]
$cap = function($f) { return strtoupper($f); };
$fruit = array_map($cap, $fruit);     // [ 'APPLE', 'BANANA', 'GRAPE', 'PEAR' ]
foreach ($fruit as $i => $f) {
  $fruit[$i] = strtolower($f);
}                                     // [ 'apple', 'banana', 'grape', 'pear' ]

© 2017 Morgan C. Benton code4your.life

Java

// import necessary external libraries
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
import java.util.stream.Collectors;

class Main {
  public static void main(String[] args) {
    ArrayList<String> fruit = new ArrayList<String>();      // create a new, empty array
    fruit.addAll(Arrays.asList("banana", "apple", "pear")); // initialize with data
    fruit.add("grape");                                     // [ "banana", "apple", "pear", "grape" ]
    fruit.add(0, "orange");                                 // [ "orange", "banana", "apple", "pear", "grape" ]
    System.out.println(fruit.size());                       // 5
    System.out.println(fruit.get(2));                       // apple
    String last = fruit.remove(fruit.size() - 1);           // [ "orange", "banana", "apple", "pear" ]
    System.out.println(last);                               // grape
    String first = fruit.remove(0);                         // [ "banana", "apple", "pear" ]
    System.out.println(first);                              // orange
    Collections.reverse(fruit);                             // [ "pear", "apple", "banana" ]
    fruit.addAll(Arrays.asList("pear", "grape"));           // [ "pear", "apple", "banana", "pear", "grape" ]
    int b = fruit.indexOf("banana");                        // b = 2
    fruit.remove(b);                                        // [ "pear", "apple", "pear", "grape" ]
    fruit.add(b, "banana");                                 // [ "pear", "apple", "banana", "pear", "grape" ]
    System.out.println(String.join(", ", fruit));           // pear, apple, banana, pear, grape
    int p2 = fruit.lastIndexOf("pear");                     // p2 = 3
    fruit.remove(p2);                                       // [ "pear", "apple", "banana", "grape" ]
    Collections.sort(fruit);                                // [ "apple", "banana", "grape", "pear" ]
    fruit = fruit.stream().map(String::toUpperCase)
      .collect(Collectors.toCollection(ArrayList::new));    // [ "APPLE", "BANANA", "GRAPE", "PEAR" ]
    for(int i = 0; i < fruit.size(); i++) {
      fruit.set(i, fruit.get(i).toLowerCase());
    }                                                       // [ "apple", "banana", "grape", "pear" ]
  }
}

© 2017 Morgan C. Benton code4your.life

Go

package main

import (
  "fmt"
  "strings"
  "sort"
)
type strSlice []string

func pos(arr strSlice, val string) int {
    for p, v := range arr {
        if (v == val) {
            return p
        }
    }
    return -1
}

func rpos(arr strSlice, val string) int {
    for i := len(arr) - 1; i >=0; i-- {
        if (arr[i] == val) {
            return i
        }
    }
    return -1
}

func ins(arr strSlice, val string, idx int) strSlice {
  end := make([]string, len(arr[idx:]))
  copy(end, arr[idx:])
  return append(append(arr[:idx], val), end...)
}

// continued in next column -->
// ...continued from column 1
func main() {
  fruit := make([]string, 5)
  fruit = []string{"banana", "apple", "pear"}
  fruit = append(fruit, "grape")
  fruit = append(append([]string{}, "orange"), fruit...)
  fmt.Println(len(fruit))
  fmt.Println(fruit[2])
  last := fruit[len(fruit) - 1]
  fmt.Println(last)
  fruit = fruit[:len(fruit) - 1]
  first := fruit[0]
  fruit = fruit[1:]
  fmt.Println(first)
  for i, j := 0, len(fruit) -1; i < j; i, j = i+1, j-1 {
    fruit[i], fruit[j] = fruit[j], fruit[i]
  }
  fruit = append(fruit, []string{ "pear", "grape"}...)
  b := pos(fruit, "banana")
  fmt.Println(b)
  fruit = append(fruit[:b], fruit[b+1:]...)
  fruit = ins(fruit, "banana", b)
  fmt.Println(strings.Join(fruit, ", "))
  p2 := rpos(fruit, "pear")
  fmt.Println(p2)
  fruit = append(fruit[:p2], fruit[p2 + 1:]...)
  sort.Strings(fruit)
  for i := 0; i < len(fruit); i++ {
    fruit[i] = strings.ToUpper(fruit[i]) 
  }
  for i := 0; i < len(fruit); i++ {
    fruit[i] = strings.ToLower(fruit[i]) 
  }
}

© 2017 Morgan C. Benton code4your.life

Multi-dimensional Arrays

  • Arrays can have an arbitrary number of dimensions
  • Think of it as an array of arrays (of arrays)
  • Most of the time, people don't use more than 2,
    e.g. for the rows and columns of a table

© 2017 Morgan C. Benton code4your.life

Two-dimensional Array Example

data[0] 88 97 65 100 88
data[1] 90 85 78 95 95
data[2] 46 68 60 75 70
index [0] [1] [2] [3] [4]
// quiz scores for three students as a 2-dimensional array
let quiz_data = [
    [88, 97, 65, 100, 88], // student 1
    [90, 85, 78,  95, 95], // student 2
    [46, 68, 60,  75, 70], // student 3
];

// output the 3rd quiz score for student 1
console.log( quiz_data[0][2] ); // output: 65

// calculate and output the average for each student
quiz_data.forEach(scores => {
    console.log(scores.reduce((a, b) => a + b / scores.length, 0));
});

// output: 87.6 88.6 63.8

© 2017 Morgan C. Benton code4your.life

Summary

Collections:

  • Are a fundamental to all programming languages
  • Have common properties and operations across them
  • May be homogeneous (arrays) or heterogeneous
    (non-arrays)
  • Contain elements identified by indices
  • May be multi-dimensional

© 2017 Morgan C. Benton code4your.life

Collections

By Morgan Benton

Collections

A brief introduction to the concept of "collections" in computer programming. Covers basic terminology and contains example code for common properties and operations in several different languages.

  • 1,062