Looping with pairs

ipairs goes through a list: 1, 2, 3… up to the first missing number. It doesn't see keys like carrot. To go through every key of a table, use pairs. In each round of the loop, it gives you one key and its value:

local barn = {carrot = 12, potato = 30, pumpkin = 4}

for crop, count in pairs(barn) do
    print(crop .. ": " .. count)
end

This prints, for example:

potato: 30
pumpkin: 4
carrot: 12

Why “for example”? Because the order of pairs isn't defined. Lua stores the keys so that it can find any of them quickly, not in the order in which you wrote them. You can't rely on any order: not the one in your code, not the alphabetical one. On this site, the order may even be different each time you click Run; try it a few times. In a bigger program, it can also change when keys are added or removed.

For many tasks, the order doesn't matter: adding up the values, counting the keys, finding the largest value. Remember that # doesn't count the keys of a dictionary? A loop does:

local barn = {carrot = 12, potato = 30, pumpkin = 4}

local kinds = 0
local total = 0
for crop, count in pairs(barn) do
    kinds = kinds + 1
    total = total + count
end
print("Kinds: " .. kinds)
print("Total: " .. total)
Kinds: 3
Total: 46

When the order does matter, for example when you print the barn for Emma, sort the keys first. Collect them into a list, sort it with table.sort, and go through the sorted list with ipairs; the values you read from the dictionary by their keys. With only one variable after for, pairs gives you just the keys:

local barn = {potato = 30, pumpkin = 4, carrot = 12}

local crops = {}
for crop in pairs(barn) do
    table.insert(crops, crop)
end
table.sort(crops)

for _, crop in ipairs(crops) do
    print(crop .. ": " .. barn[crop])
end

This prints the same lines in the same order every time:

carrot: 12
potato: 30
pumpkin: 4

With a comparison function from the lesson on functions, you can sort by the values instead: table.sort(crops, function(a, b) return barn[a] > barn[b] end) puts the crop with the most pieces first.

pairs works on lists too (their keys are 1, 2, 3…), but it doesn't promise to go in order. For lists, use ipairs.

Typical mistakes:

  • ipairs(barn) instead of pairs(barn): the table has no key 1, so the loop runs zero times. Nothing is printed and there's no error, so watch out for it.
  • Forgetting pairs: for crop, count in barn do ends with attempt to call a table value (for iterator 'for iterator').
  • Adding new keys to the table while pairs goes through it. Changing or removing the keys the loop gives you is fine, but don't add new ones in the loop.

Instructions

With a for loop and pairs, print every crop in the barn with its count. The lines may come in any order, for example:

wheat: 50
carrot: 12
pumpkin: 4
potato: 30

Below, count the kinds of crops in the barn and add up all the pieces. Print:

Kinds: 4
Total: 96

Finally, print In order: and below it the crops again, this time sorted alphabetically:

In order:
carrot: 12
potato: 30
pumpkin: 4
wheat: 50

Start programming for free

By signing up, you agree to the Terms of Service and Privacy Policy.

Or sign up with:

4/10