Reputation:
This might seem as a basic question..but I'm confused regarding how to achieve this with the new swift syntax. On the click of a button on the collection view I'm having something like this....
let productObject = productData1[(indexPath?.row)!]
self.myArray.append(productObject)
Now when I click on that button again I want to check if myArray
has the productObject
already so that it will not be added to the array again...Hope somebody can help...
EDIT: productData1 is a type of struct Product like so...
struct Product {
let name : String
let id : String
var images = [ProductImage]()
var theRate : String
var quantity: String
var sku: String
var prdCateg: String
var prodDescr: String
var mrp: String
var prodcutImage: ProductImage?
init(name : String, id: String, theRate: String, quantity: String, sku: String, prdCateg:String, prodDescr: String, prodcutImage: ProductImage?, mrp: String) {
self.name = name
self.id = id
self.theRate = theRate
self.quantity = quantity
self.sku = sku
self.prdCateg = prdCateg
self.prodDescr = prodDescr
self.prodcutImage = prodcutImage
self.mrp = mrp
}
mutating func add(image: ProductImage) {
images.append(image)
}
}
Upvotes: 1
Views: 101
Reputation: 46
If you don't care about the order of your objects inside myArray
, one solution would be do use a Set
.
First of all you'll need to make your struct Product
compliant to Hashable
.
By taking a look at your struct we can assume that two products are equals if their IDs are equals.
extension Product: Hashable {
var hashValue: Int { return id.hashValue}
static func ==(lhs: Product, rhs: Product) -> Bool {
return lhs.id == rhs.id
}
}
You redefine myArray
as followed:
var myArray: Set<Product> = [] // Creating the Set of `Products`
// inserting product with id "123"
myArray.insert(Product(name: "name",
id: "123",
images: [],
theRate: "",
quantity: "",
sku: "",
prdCateg: "",
prodDescr: "",
mrp: "", prodcutImage: nil))
// Trying to insert product with id "123" but it already exists,
// It won't be added to myArray
myArray.insert(Product(name: "name",
id: "123",
images: [],
theRate: "",
quantity: "",
sku: "",
prdCateg: "",
prodDescr: "",
mrp: "", prodcutImage: nil))
print(myArray.count) // 1
Upvotes: 1
Reputation: 61
ProductImage should conform protocol Equatable. Then you can check is objects of ProductImage are the same, and accordingly is images.contains(image) before add new one.
To conform protocol you need to implement func == for ProductImage.
Something like
func ==(lhs: ProductImage, rhs: ProductImage) -> Bool {
return lhs.imageUrl == rhs.imageUrl
}
Upvotes: 0
Reputation: 685
Here are 2 solutions. The first one is more efficient IMO.
SOLUTION I - maintain additional Mapping Data Source
var myArray: [Product] = []
var myDictionary: [String : Product] = [:]
func add(newProduct product: Product) {
// Add only if product isn't contained in datasource (Test in O(1))
guard myDictionary[product.id] == nil else {
return
}
myArray.append(product)
myDictionary[product.id] = product
}
Memory motivation / consideration: The memory cost of additional data-source is relatively low because of the lazy manner that Swift language copies structs. Both array and dictionary hold the same instances of Products until their inner content is changed.
SOLUTION II (Less efficient) - use contains method of the collection view (Iterate the array every time
var myArray: [Product] = []
func add(newProduct product: Product) {
// Test while `contains`
guard !myArray.contains { $0.id == product.id } else {
return
}
myArray.append(product)
}
Upvotes: 0
Reputation: 94
Hope this will help you..
let productObject = productData1[(indexPath?.row)!]
let filteredArray = self.myArray.filter(){
return $0.id == productObject.id
}
if filteredArray.count == 0 {
self.myArray.append(productObject)
}
Upvotes: 0