3

Im new to swift language and I'm trying to find a solution for my problem. I have created a class called Book

I am tring to create Book. A book has name (can’t be changed after creation), purchaseid (can’t be changed after creation), and market price (can be changed)

and also a class Shelf. A shelf has name (that can’t be changed after creation) and an array of books (that can be changed by calling add and delete methods and is unique on book purchaseId - ie. doesn’t have duplicate purchaseIds). Shelf also has a method for computing the average price of books in the shelf.

I am trying to find a solution on how to check an array before adding to it and taking books purchaseId and deleting a book from the array.

here is my code:

class Book{
    let name: String
    let purchaseID: Int
    let marketPrice: Double




    init(name: String, purchaseID: Int, marketPrice: Double) {
        self.name = name
        self.purchaseID = purchaseID
        self.marketPrice = marketPrice
    }


    func bookPrinter() -> String {
        return "Name: \(self.name) Price: \(marketPrice)"

    }

}

class Shelf{
    private let shelfName: String
    private var arrayOfBooks = [Book]()


    init(shelfName: String) {
        self.shelfName = shelfName
    }

    func add(book : Book ){
   
    
    }

   
    func delete(book : Book){

    }


    func printer() {
        for b in self.arrayOfBooks{
            print(b.bookPrinter())
        }
    }

}
3
  • You mean that purchaseId uniquely identifies a Book?
    – gcharita
    Commented Oct 29, 2020 at 19:21
  • 1
    If the order of the books on the shelf doesn't matter you should use a Set
    – Leo Dabus
    Commented Oct 29, 2020 at 19:23
  • Yes, I mean that purchaseId uniquely identifies a Book Commented Oct 29, 2020 at 19:43

1 Answer 1

3

For add(book:) function, if the book's purchaseID is unique, you can use contains(where:) function to know if the Book already exists in the Array:

func add(book: Book){
    if !arrayOfBooks.contains(where: { $0.purchaseID == book.purchaseID }) {
        arrayOfBooks.append(book)
    }
}

or add an extension to Book that conforms to Equatable protocol:

extension Book: Equatable {
    static func == (lhs: Book, rhs: Book) -> Bool {
        return lhs.purchaseID == rhs.purchaseID
    }
}

and simplify your add(book:) function:

func add(book: Book){
    if !arrayOfBooks.contains(book) {
        arrayOfBooks.append(book)
    }
}

For delete(book:) function you can use removeAll(where:) function of Array:

func delete(book: Book){
    arrayOfBooks.removeAll(where: { $0.purchaseID == book.purchaseID })
}

However, as @LeoDabus said in the comments, if book ordering doesn't mater you should probably use a Set. It will be faster on some aspects.

An implementation may be like this:

extension Book: Hashable {
    static func == (lhs: Book, rhs: Book) -> Bool {
        return lhs.purchaseID == rhs.purchaseID
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(purchaseID)
    }
}

class Shelf {
    private let shelfName: String
    private var setOfBooks = Set<Book>()

    init(shelfName: String) {
        self.shelfName = shelfName
    }

    func add(book: Book){
        setOfBooks.insert(book)
    }

    func delete(book: Book){
        setOfBooks.remove(book)
    }
}
1
  • I updated my question. Thank you for your quick response. Commented Oct 29, 2020 at 19:15

Not the answer you're looking for? Browse other questions tagged or ask your own question.