Sets - School Roster - Challenge 1

Hello,

I am having some trouble with the first Challenge problem for the School Roster project. I am including my code below. Could anyone shed some light? I feel like my logic is on the right track, but please let me know. Thanks!

  • The student "Skyla" has transferred to a new school. Use .remove() to delete the student from any classes they are currently enrolled in.

var classSet: Set = [spanish101, german101, englishLiterature, computerScience, artHistory, advancedCalculus]

//Challenge 1
for individualSet in classSet {
if individualSet.contains(“Skyla”) {
print(individualSet)
} else {
continue
}
}

@dataace07981, welcome to the forums!

Yes, you’re on the right track. Right now your loop is printing the classes that Skyla is enrolled in. Instead of printing them, the prompt tells you to remove her from them using the .remove() method.

So, what would you replace your print statement with?

Hello,

I changed the code and am still receiving an error. I am including my new code below:

//Challenge 1
for individualSet in classSet {
if individualSet.contains(“Skyla”) {
individualSet.remove(“Skyla”)
} else {
continue
}
}

The console error I receive is:

Roster.swift:44:5: error: cannot use mutating member on immutable value: ‘individualSet’ is a ‘let’ constant
individualSet.remove(“Skyla”)
^~~~~~~~~~~~~

I also tried renaming “classSet” as a “let” variable, still no dice. Any more suggestions? I know it’s my syntax, correct? I cannot find solutions for the challenge problems, unlike the previous units.

Thank you!

Thanks for bringing this up!

Now, before I get into the weeds on this, I’ll just put it out there that I think @sonnynomnom and @realkennylin expected learners to use .remove from the inidividual sets containing “Skyla”, rather than looping over classSet. But, trying to do so actually brings up some really interesting nuances of Swift. So, if you’re interested, feel free to read on.

There are actually two challenges here.

The first is that when you use a for loop in Swift, the temporary value (in this case individualSet) is initialized as a constant, rather than a variable. This is triggering the error you have now.

Normally, this would be a simple fix, by telling the for loop to use a variable instead of a constant:

// notice the "var" here
for var individualSet in classSet{
   ...do something here...
}

However, sets in Swift are both value types (as opposed to reference types) and they are unsubscriptable. Don’t worry if you don’t fully understand what that means yet. It’s more important that you understand how it affects what you’re trying to do.

Because sets are value types, when we loop over the inner sets using the for loop, we are not actually accessing the original inner sets—we are accessing a copy of them. So, even if we use the syntax above…

for var individualSet in classSet{
    if individualSet.contains("Skyla") {
        individualSet.remove("Skyla")
    }
}

we won’t be removing "Skyla" from the the actual set inside of classSet. We will be removing it from the temporary copy we made during the for loop.

Now, if sets in Swift were subscriptable like arrays are, we could loop through the number of elements and access the original inner sets by using their index number. However, take a look at what happens when we try to do that:

for i in 0..<classSet.count {
  print(classSet[i])
}

// output
main.swift:58:17: error: cannot subscript a value of type 'Set<Set<String>>' with an index of type 'Int'

So what can we do here?

Well, if we want to maintain a set of sets, we can make a new empty set and insert the inner set copies into the new set as we loop through.

Or, if we don’t need each value in our class rosters to be unique, we can use an array of arrays (which is probably more appropriate, since classes can have two people with the same name) and then loop through the number of elements like we tried to above.

If you’d like to see how this can be done, check out my repl.it example below:
https://repl.it/@elCocodrilo/SwiftCollectionTypeNuances

You can run and alter the code in there to test out my examples.

Hope this helped! Happy coding!

2 Likes