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? 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 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)
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

I updated my question. Thank you for your quick response.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.