Reputation: 137
I am writing an iOS App in Swift 4.2 I am looping through array 1 and making changes to its one element and adding those elements to array 2.
Array:
let array:[model] = []
let array2:[model] = []
Model for this array is:
class model: NSObject {
var id:Int = 0
var name:String=""
var isChecked:Bool=false
}
Function:
func customCheckboxValueChangedWithID(_ id: Int, isChecked: Bool) {
array2.removeAll()
//TODO, use sugar syntax/higher order function for this loop:
for element in array{
if(element.id==id){
element.isChecked=isChecked
if(element.isChecked){
array2.append(element)
}
}
}
reloadCollectionView()
}
How to convert this into swift higher order function, like map
, flatMap
, etc?
Upvotes: 2
Views: 3027
Reputation: 3536
You can try this:
class MyObj: CustomStringConvertible {
var id: String
var isChecked: Bool
init(id: String = "", isChecked: Bool = false) {
self.id = id
self.isChecked = isChecked
}
var description: String {
return "MyObj(id: \(id), isChecked: \(isChecked)"
}
}
let array = [
MyObj(id: "id1"),
MyObj(id: "id1", isChecked: true),
MyObj(id: "id2"),
MyObj(id: "id3", isChecked: true)
]
func customCheckboxValueChanged(_ values: [MyObj], id: String, isChecked: Bool) -> [MyObj] {
let sameIDModels: [MyObj] = values
.filter { $0.id == id }
.map { $0.isChecked = isChecked; return $0 }
return sameIDModels.filter{ $0.isChecked }
}
let isChecked = true
let myID = "id1"
print(customCheckboxValueChanged(array, id: myID, isChecked: isChecked))
Upvotes: 0
Reputation: 985
You can use Filter
numbers.forEach({ if $0.id == id { $0.isChecked = isChecked } })
(Copied SPatel's comment)
Loops over a collection and returns an array that contains elements that meet a condition.
Let’s assume we need to filter even numbers only in the following array example. The traditional approach can be:
let numbersArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15]
// The traditional way
var evenNumArray: [Int] = []
for number in numbersArray {
if number % 2 == 0 {
evenNumArray.append(number)
}
}
// evenNumArray = [2, 4, 6, 8, 10, 14]
Instead, let’s use filter for the same result:
let numbersArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14, 15]
// Filter
let evenArray = numbersArray.filter { $0 % 2 == 0 }
Simple Higher Order Functions in Swift
Upvotes: 0
Reputation: 21
how about using 'flatMap'
here is playground source
//: Playground - noun: a place where people can play
import UIKit
struct model {
var id:Int = 0
var name:String=""
var isChecked:Bool=false
}
let array:[model] = [model(id: 0, name: "0", isChecked: false),
model(id: 1, name: "1", isChecked: false),
model(id: 2, name: "2", isChecked: false),
model(id: 3, name: "3", isChecked: false),
model(id: 4, name: "4", isChecked: false),
model(id: 5, name: "5", isChecked: false),
model(id: 6, name: "6", isChecked: false)
]
var array2:[model] = []
func customCheckboxValueChangedWithID(_ id: Int, isChecked: Bool) {
array2 = array.flatMap { (ma: model) -> model? in
var element = ma
if element.id == id {
element.isChecked = isChecked
return element
}
return nil
}
}
customCheckboxValueChangedWithID(1, isChecked: true)
print("array2 : \(array2)")
result: array2 : [__lldb_expr_53.model(id: 1, name: "1", isChecked: true)]
Upvotes: 0
Reputation: 77651
You can rewrite this like...
array.forEach {
if $0.id == someID { $0.isChecked = isChecked }
}
This only works because you are using classes.
If you switch to using structs then you could have...
let newArray = array.map {
if $0.if == someID {
var theModel = $0
theModel.isChecked = isChecked
return theModel
}
return $0
}
Upvotes: 0
Reputation: 130152
Since you have an array of classes, this is very simple:
let array: [model] = [...]
array.first { $0.id == id }?.isChecked = isChecked
If you had an array of structs, you would either need to update the original array or create a whole new array:
var array: [model] = []
// updating element in the original array
if let index = array.index(where: { $0.id == id }) {
array[index].isChecked = isChecked
}
// updating the whole array
array = array.map {
guard $0.id == id else { return $0 }
var element = $0
element.isChecked = isChecked
return element
}
Upvotes: 1
Reputation: 6110
You can do it this way:
array.forEach { if $0.id == id { $0.isChecked.toggle() } }
If you just want to filter the elements and only leave the elements whose isChecked
property set to true
, you can use this:
let newArray = array.filter { $0.isChecked }
Upvotes: 6