Search code examples
swiftuiswiftui-list

SwiftUI - How to display the total of the previous and current item with ForEach loop?


I am getting following result with the code added below:

name: A amount: 100.50 Total: 236.67

name: B amount: 50.52 Total: 236.67

name: C amount: 85.65 Total: 236.67

Instead, I would like to display the following results at each ForEach loop

name: A amount: 100.50 Total: 100.50

name: B amount: 50.52 Total: 151.02

name: C amount: 85.65 Total: 236.67

Below is the coding details:-

import SwiftUl

struct NameAmount: Identifiable {

let id = UUID()

let name: String
let amount: Double

}
struct ContentView: View {

let transactions: [NameAmount] = [
    NameAmount(name: "A", amount: 100.50),
    NameAmount (name: "B", amount: 50.52),
    NameAmount (name: "C", amount: 85.65)
]
var body: some View {
VStack {``
    List {
        VStack {
            ForEach(transactions) { item in
                HStack {
                    Text(item.name)
                    Text("(String (format: "%.2f", item.amount))")
                    Spacer()
                    Text("Total: (String(format: '%.2f", transactions.reduce(0)($0 +    $1.amount))")

}
}
}
}
}
}
}

Text("Total: (String(format: '%.2f", transactions.reduce(0)($0 + $1.amount))") // the .reduce code is displaying the total of 236.67 at each foreach loop.

Instead, I would like to display the following results at each ForEach loop

name: A amount: 100.50 Total: 100.50

name: B amount: 50.52 Total: 151.02

name: C amount: 85.65 Total: 236.67


Solution

  • You can do it if you have the current index and use a subset of transactions [0...index]

    struct PartialSunView: View {
        struct NameAmount: Identifiable {
            
            let id = UUID()
            
            let name: String
            let amount: Double
            
        }
        
        let transactions: [NameAmount] = [
            NameAmount(name: "A", amount: 100.50),
            NameAmount (name: "C", amount: 50.52),
            NameAmount (name: "B", amount: 85.65)
        ]
        var filtered: [NameAmount]{
            transactions.sorted(using: KeyPathComparator(\.name))
        }
        var body: some View {
            VStack {
                List {
                    VStack {
                        ForEach(Array(filtered.enumerated()), id:\.offset) { (index, item) in //Get current index
                            HStack {
                                Text(item.name)
                                Text(String (format: "%.2f", item.amount))
                                Spacer()
                                Text("Total: \(String(format: "%.2f", filtered[0...index].reduce(0){$0 + $1.amount}))")//Use subset
                                
                            }
                        }
                    }
                    
                }
            }
        }
    }