Home > Software design >  I tried to get the index of an element from Core Data, but it shows an error even I force unwrapped
I tried to get the index of an element from Core Data, but it shows an error even I force unwrapped

Time:02-04

I try to use a function to sorted the data in the Core Data, and get the firstIndex of the first element base on the predicate, but when I used .firstIndex, it shows:

Value of type '((Filedetails) -> Array.Index?)?' (aka 'Optional<(Filedetails) -> Optional>') has no member 'compactMap'"

func countingLastOccurrence(filterkey1: String) -> Int {

        let context = PersistenceController.shared.container.viewContext

        let fetchquest1 = NSFetchRequest<Filedetails>(entityName: "Filedetails")

        fetchquest1.sortDescriptors = [NSSortDescriptor(keyPath: \Filedetails.year, ascending: false), NSSortDescriptor(keyPath: \Filedetails.sequence, ascending: false)]

        fetchquest1.predicate = NSPredicate(format: "%K == 1", filterkey1)

        let item1 = try? context.fetch(fetchquest1).firstIndex

       let item1a = item1.compactMap { Int($0) }

        return item1a

I had tried to force unwrapped the value, but it is error

"Cannot assign value of type '(Filedetails) -> Array.Index?' (aka '(Filedetails) -> Optional') to type 'Int'"

var item1a: Int = 0
        if let item1 = try? context.fetch(fetchquest1).firstIndex {
            item1a  = item1
        }
        return item1a

I tried "if let" and "guard let"

guard let item1 = try? context.fetch(fetchquest1).firstIndex  else {
            return 0
        }
return item1

It still shows an error:

Cannot convert return expression of type '(Filedetails) -> Array.Index?' (aka '(Filedetails) -> Optional') to return type 'Int'

If I used .first for the predicate, I can get the details of the data, but when I used .firstIndex, I can't get the result.

How can I get the index as a Int ?

Thank you so much.

CodePudding user response:

The problem is that your code generates two optionals, one by try? and one by first(Index).

The first index of the first element base on the predicate is always zero so it doesn't make much sense to return the index especially to return 0 in case of an error.

Calling compactMap is also pointless because both input and output is an array. It just skips the nil values.

To avoid the double optional you could return an optional Filedetails item

func countingLastOccurrence(filterKey: String) -> Filedetails? {
    
    let context = PersistenceController.shared.container.viewContext
    let request = NSFetchRequest<Filedetails>(entityName: "Filedetails")
    request.sortDescriptors = [NSSortDescriptor(keyPath: \Filedetails.year, ascending: false), NSSortDescriptor(keyPath: \Filedetails.sequence, ascending: false)]
    request.predicate = NSPredicate(format: "%K == 1", filterKey)
    guard let result = try? context.fetch(request) else { return nil}
    return result.first
}

Or hand over the error to the caller

func countingLastOccurrence(filterKey: String) throws -> Filedetails? {
    
    let context = PersistenceController.shared.container.viewContext
    let request = NSFetchRequest<Filedetails>(entityName: "Filedetails")
    request.sortDescriptors = [NSSortDescriptor(keyPath: \Filedetails.year, ascending: false), NSSortDescriptor(keyPath: \Filedetails.sequence, ascending: false)]
    request.predicate = NSPredicate(format: "%K == 1", filterKey)
    return try context.fetch(request).first
}

Side note: Consider a better naming than the 1 and 1a suffixes which are a bit confusing

  • Related