Hehcate
Hehcate

Reputation: 41

Using filter function with minimum and maximum values

I am trying to sort the items that are in a list with a user inputted min and max.

Code for context:

enum Category: Comparable {
    case attack
    case healing
    case support
}

typealias Spell = (name: String, cat: Category, cost: Int)

let startingSpellList: [Spell] = [
    ("Poison", .attack, 3),
    ("Bio", .attack, 26),
    ("Fire", .attack, 4),
    ("Fire 2", .attack, 20),
    ("Fire 3", .attack, 51),
    ("Ice", .attack, 5),
    ("Ice 2", .attack, 21),
    ("Ice 3", .attack, 52),
    ("Bolt", .attack, 6),
    ("Bolt 2", .attack, 22),
    ("Bolt 3", .attack, 53),
    ("Pearl", .attack, 40),
    ("Quake", .attack, 50),
    ("Break", .attack, 25),
    ("Doom", .attack, 35),
    ("Flare", .attack, 45),
    ("Meteor", .attack, 62),
    ("Ultima", .attack, 80),
    
    ("Cure", .healing, 5),
    ("Cure 2", .healing, 25),
    ("Cure 3", .healing, 40),
    ("Regen", .healing, 10),
    ("Life", .healing, 30),
    ("Antidote", .healing, 3),
    ("Remedy", .healing, 15),
    
    ("Imp", .support, 10),
    ("Haste", .support, 10),
    ("Safe", .support, 12),
    ("Shell", .support, 15),
    ("Berserk", .support, 16),
    ("Float", .support, 17),
    ("Reflect", .support, 22),
    ("Quick", .support, 99),
    ("Scan", .support, 3),
    ("Sleep", .support, 5),
    ("Slow", .support, 5),
    ("Mute", .support, 8),
    ("Confuse", .support, 8),
    ("Stop", .support, 10)
]

func spellString(_ spell: Spell) -> String {
    let name = spell.name.padding(toLength: 8, withPad: " ", startingAt: 0)
    
    let type: String
    switch spell.cat {
    case .attack:
        type = "(Attack) "
    case .healing:
        type = "(Healing)"
    case .support:
        type = "(Support)"
    }
    
    let cost = (spell.cost < 10) ? " " + String(spell.cost) : String(spell.cost)
    
    return "\(name) \(type) - \(cost) MP"
}

I want the user to be asked to input a min and max value, and then use the filter higher order function to filter and print all the spells that have an MP(cost) in between those values.

I have tried this:

func selectByCost(_ spells: [Spell]) -> [Spell] {
    print("Enter the minimum MP cost: ")
    let min = readLine()!
    print("Enter the maximum MP cost: ")
    let max = readLine()!
    
    if Spell.Int == min...max {
        ???
    }

I tried spell.Int= min.max but I get the error that "Value of tuple type 'Spell' (aka '(name: String, cat: Category, cost: Int)') has no member 'Int'" I am sorry I dont know much about coding if this is a common mistake

Upvotes: 0

Views: 425

Answers (1)

jnpdx
jnpdx

Reputation: 52515

Here's an example with filter:

func selectByCost(_ spells: [Spell]) -> [Spell] {
    print("Enter the minimum MP cost: ")
    let min = readLine()!
    print("Enter the maximum MP cost: ")
    let max = readLine()!
    
    //You'll have to account for what happens if the user enters invalid numbers
    guard let minNumber = Int(min), let maxNumber = Int(max) else {
        assertionFailure("Not valid numbers")
        return []
    }
    
    //Here's the filter function -- it returns items that meet both criteria
    return spells.filter { $0.cost >= minNumber && $0.cost <= maxNumber }
}

If you also check for validity of the range (eg min has to be < max), you could do something like this:

guard let minNumber = Int(min), let maxNumber = Int(max) else {
    assertionFailure("Not valid numbers")
    return []
}

guard minNumber < maxNumber else {
    assertionFailure("Invalid range")
    return []
}

let range = (minNumber...maxNumber)

return spells.filter { range.contains($0.cost) }

Upvotes: 2

Related Questions