Search code examples
arraysswiftcore-datauikit

Create new array when button is pressed


I want to create a new array every time when a button (ActionButton) is pressed. When this button is pressed the first time then a new array should be created and 10 should be added. When the button is pressed the second time then another new array should be created and add 20. And so on. I would like to also save the created arrays in Core Data. In this case the named error occured. But when change from let to var then it is only 1 array and it will be overwritten every time right? Could you be so kind and show me which code is right to create a new array, add the current value, and save it.

import UIKit
import CoreData

class ViewController: UIViewController {

    var number : Double = 0
    
    //  Reference to Managed Object Context
    let context = (UIApplication.shared.delegate as!     AppDelegate).persistentContainer.viewContext

    var average : Stats?
    var array : Stats?
    
//-------------------------------------------------------------------------------------
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        fetchStats()
        
    }
//-------------------------------------------------------------------------------------
    @IBAction func ActionButton(_ sender: UIButton) {

        number += 10.0
        average?.value = number
        
        //Idea
        let newarray = [Double]()
        newarray.append(number)
        array?.new = newarray
        
        //Error message by .append:
            //Cannot use mutatingChange 'let' to 'var' to make it mutable member on                                            immutable value: 'TestArray' is a 'let' constant
            //Change 'let' to 'var' to make it mutable
        
        
        saveData()
    
    }
    
//-------------------------------------------------------------------------------------
    func fetchStats() {
        
    //Fetch the data from CoreData to display in the View
    do {
        if let found = try context.fetch(Stats.fetchRequest()).first {
            average = found
            number = found.value
            
            array = found
            newarray = found.new
            
        } else {
            average = Stats(context: context)
            average?.value = 0
            
            array = Stats(context: context)
            array?.new = []
            
            saveData()
        }
                    
    }
    catch {
        print(error)
        }
    }
//-------------------------------------------------------------------------------------
    func saveData() {
        do {
            try context.save()
        } catch {
            print(error)
        }
    }
}

Solution

  • It's not clear why you want multiple single-element arrays, but assuming you have a valid reason...

    You want to use an "array of arrays". With each button tap, you will append a new array to the "array of arrays":

    class ViewContoller: UIViewController {
        
        var number : Double = 0
        var theArrays: [[Double]] = []
        
        @IBAction func ActionButton(_ sender: UIButton) {
            
            number += 10.0
            theArrays.append([number])
            
            print() // blank line
    
            for i in 0..<theArrays.count {
                print("Array \(i):", theArrays[i])
            }
    
            print() // blank line
    
            print("theArrays:", theArrays)
    
            print() // blank line
            print("-----------")
        }
    
    }
    

    If you tap the button 4 times, this is what you'll see in the debug console:

    Array 0: [10.0]
    
    theArrays: [[10.0]]
    
    -----------
    
    Array 0: [10.0]
    Array 1: [20.0]
    
    theArrays: [[10.0], [20.0]]
    
    -----------
    
    Array 0: [10.0]
    Array 1: [20.0]
    Array 2: [30.0]
    
    theArrays: [[10.0], [20.0], [30.0]]
    
    -----------
    
    Array 0: [10.0]
    Array 1: [20.0]
    Array 2: [30.0]
    Array 3: [40.0]
    
    theArrays: [[10.0], [20.0], [30.0], [40.0]]
    
    -----------
    

    Edit - to answer comment...

    If you want to add 5 numbers to each "sub-array" we can add a currentIndex property to track the sub-arrays within the "main" array.

    When we've appended 5 numbers to the array at currentIndex, we will increment currentIndex and append a new, empty array to the "main" array.

    class ViewContoller: UIViewController {
        
        var number : Double = 0
        var theArrays: [[Double]] = []
        
        // to track which sub-array we're appending new numbers to
        var currentIndex: Int = 0
        
        @IBAction func ActionButton(_ sender: UIButton) {
            
            number += 10.0
            
            // if theArrays is empty
            if theArrays.isEmpty {
                // that means this is the very first time button was tapped
                //  so append an empty array to theArrays
                theArrays.append([])
                // set currentIndex to Zero, in case
                //  it has been changed somewhere else
                currentIndex = 0
            }
    
            // if the array at currentIndex has 5 elements
            if theArrays[currentIndex].count == 5 {
                // increment currentIndex
                currentIndex += 1
                // append an empty array to theArrays
                theArrays.append([])
            }
            
            // append number to the array at currentIndex
            theArrays[currentIndex].append(number)
            
            print() // blank line
            
            for i in 0..<theArrays.count {
                print("Array \(i):", theArrays[i])
            }
    
            print() // blank line
    
            print("theArrays:", theArrays)
    
            print() // blank line
            print("-----------")
        }
    
    }
    

    Now, after tapping 27 times, we'll see this in the debug console:

    -----------
    
    Array 0: [10.0, 20.0, 30.0, 40.0, 50.0]
    Array 1: [60.0, 70.0, 80.0, 90.0, 100.0]
    Array 2: [110.0, 120.0, 130.0, 140.0, 150.0]
    Array 3: [160.0, 170.0, 180.0, 190.0, 200.0]
    Array 4: [210.0, 220.0, 230.0, 240.0, 250.0]
    Array 5: [260.0, 270.0]
    
    theArrays: [[10.0, 20.0, 30.0, 40.0, 50.0], [60.0, 70.0, 80.0, 90.0, 100.0], [110.0, 120.0, 130.0, 140.0, 150.0], [160.0, 170.0, 180.0, 190.0, 200.0], [210.0, 220.0, 230.0, 240.0, 250.0], [260.0, 270.0]]
    
    -----------