Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Error when using higher order function reduce

I am working on a function that takes the total cost of all the "MP" in a value and adds it up. Here is my code for context.

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),

Here is the function :

func totalCost(_ spells: [Spell]) -> Int {
let cost = spells.cost
let sum = cost.reduce(0, +)
return sum

}

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

With this code, I get the error that `"Value of type ‘[Spell]’ (aka ‘Array<(name: String, cat: Category, cost: Int)>’) has no member ‘cost’."
How should I fix this error?

>Solution :

spells is a [Spell], which is shorthand for Array<Spell>, and Array<Spell> doesn’t have a cost property. Each individual Spell in the array has its own cost property. You could say this to get an array of the spell costs and sum the costs array:

func totalCost(_ spells: [Spell]) -> Int {
    let costs = spells.map { $0.cost }
    let sum = cost.reduce(0, +)
    return sum
}

Or you could use a key-path literal, which can act as a function:

func totalCost(_ spells: [Spell]) -> Int {
    let costs = spells.map(\.cost)
    let sum = cost.reduce(0, +)
    return sum
}

However, using map that way creates a temporary array to hold the costs, and that’s wasteful. You can avoid the temporary array by using the .lazy operator first:

func totalCost(_ spells: [Spell]) -> Int {
    let costs = spells.lazy.map(\.cost)
    let sum = cost.reduce(0, +)
    return sum
}

Or you can fuse the extraction of cost and the summation:

func totalCost(_ spells: [Spell]) -> Int {
    let sum = cost.reduce(0) { $0 + $1.cost }
    return sum
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading