Skip to content
FutureBlitz

    Install

    Collections, 2 of 6

    Indexing and ranges

    Read and change values by index, copy part of an array with a slice, and count with ranges.

    What you’ll build

    A week’s temperature log: a program that corrects one day’s reading, looks at the weekdays and the weekend apart, and counts through the days with ranges. It picks out one value with an index, copies part of the week with a slice, counts with a range, and works on part of the week in place with a view.

    Indexes

    temps[i] reads the value at index i, and temps[i] = value replaces it. An indexed value works with +=, ++, and the other assignments too. Indexes count from 0, so a week’s days are 0 to 6.

    week.fb
    Import std.core
    
    Local days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
    Local temps = [12, 15, 19, 23, 21, 16, 11]
    
    temps[2] = 18
    temps[6] += 2
    Print("{days[2]}: {temps[2]}, {days[6]}: {temps[6]}")
    Print("the last day is {days[days.Count - 1]}")
    Output
    Wed: 18, Sun: 13
    the last day is Sun

    Slices

    temps[a..b] is a slice: a new array holding the values from index a up to b, without the one at b. Leaving out the start begins at 0, and leaving out the end goes to the last value. A slice is a copy, so changing it leaves the array as it was.

    week.fb
    Import std.core
    
    Local temps = [12, 15, 19, 23, 21, 16, 11]
    Local weekdays = temps[..5]
    Local weekend = temps[5..]
    Local midweek = temps[1..4]
    Print(weekdays, weekend, midweek)
    
    midweek[0] = 99
    Print(temps[1])
    Output
    [12, 15, 19, 23, 21] [16, 11] [15, 19, 23]
    15

    A slice’s bounds must be inside the array, with the start no greater than the end. Here temps[5..9] would panic, saying which slice it was and how many elements the array has.

    Ranges

    a To b counts from a to b, both included, and a Until b stops before b. Step counts by another amount. A range is a value of its own, which a For loop goes over and which has Methods like Sum and ToArray. A range’s Method needs the range in parentheses. The average converts both sides to Floats first, since dividing two Ints would drop the fraction.

    week.fb
    Import std.core
    
    Local temps = [12, 15, 19, 23, 21, 16, 11]
    
    Local total = 0
    For i In 0 Until temps.Count
        total += temps[i]
    End For
    Local average = (total As Float) / (temps.Count As Float)
    Print("average {average:.1}")
    
    Local everyOther = 0 Until temps.Count Step 2
    For i In everyOther
        Print("day {i}: {temps[i]}")
    End For
    Print((1 To 7).Sum(), (7 To 1 Step -2).ToArray())
    Output
    average 16.7
    day 0: 12
    day 2: 19
    day 4: 21
    day 6: 11
    28 [7, 5, 3, 1]

    Views

    A slice copies. A view doesn’t: temps.View(a, b) reads and writes the same values as the array, from index a up to b, so a change through either shows in both. A view is indexed from 0, like an array of its own.

    week.fb
    Import std.core
    Import std.collections
    
    Local temps = [12, 15, 19, 23, 21, 16, 11]
    Local weekend = temps.View(5, 7)
    weekend[0] = 17
    weekend[1] = 13
    Print(temps)
    Print(weekend.Count, weekend)
    Output
    [12, 15, 19, 23, 21, 17, 13]
    2 [17, 13]

    A type of your own can be indexed too, with [] and []= Operators; Operators on your own types shows how.

    What you learned

    • array[i] reads and writes a value, and works with += and ++.
    • array[a..b] is a slice, a copy of the values from a up to b; [..b] and [a..] leave out an end.
    • a To b and a Until b, with an optional Step, are ranges, which loops go over.
    • A range has Methods like Sum and ToArray.
    • View(a, b) gives part of an array without copying it.

    Report an issue with this page or with FutureBlitz on GitHub.