Site icon AppTractor

Просим ИИ сделать рефакторинг Swift кода

В последнее время я добавляю в Elite Hoops исправления, связанные с “качеством жизни” платформы. Среди них —  быстрые действия на главном экране (Home Screen Quick Actions).

Прошла некоторое время с тех пор, как я создавал динамические действия, так что я забыл, сколько кода может быть задействовано. Я хотел динамическое быстрое действие для каждой недавно просмотренной команды в Elite Hoops. Но это также означает, что…

В общем, одна из тех сложных и легких задач.

let concatenatedThoughts = """

На самом деле, последний раз я писал Home Scren Quick Actions для главы в моей книге. На которую, собственно, я и опирался при реализации этих действий. Сейчас я как раз занимаюсь выпуском обновления для нее, загляните, если еще не успели. Пять книг, одна цена навсегда.

"""

Вот функция, которую я написал изначально:

// This function is kind of hard to read - can you make it simpler?  

func updateQuickActionsForCourts() {
    if appSettings.quickActionCourtsToAdd.isEmpty &&
       appSettings.quickActionCourtsToRemove.isEmpty {
        return
    }
    
    var quickActions: [UIApplicationShortcutItem] = UIApplication.shared.shortcutItems ?? []
    
    // Any removals?
    var removalIndices: [Int] = []
    appSettings.quickActionCourtsToRemove.forEach { courtIDToRemove in
        for (index, item) in quickActions.enumerated() {
            let courtID = item.userInfo?["courtID"] as? Int64 ?? 0
            if courtIDToRemove == courtID {
                removalIndices.append(index)
            }
        }
    }
    
    removalIndices.forEach { removalIndex in
        quickActions.remove(at: removalIndex)
    }
    
    // Any additions?
    appSettings.quickActionCourtsToAdd.forEach { court in
        if quickActions.filter({ item in
            let courtID = item.userInfo?["courtID"] as? Int64 ?? 0
            return courtID == court.id
        }).isEmpty {
            quickActions.append(court.quickAction())
        }
    }
    
    UIApplication.shared.shortcutItems = quickActions.reversed()
    
    appSettings.quickActionCourtsToAdd.removeAll()
    appSettings.quickActionCourtsToRemove.removeAll()
}

Это некрасиво, но работает. Поэтому мне стало интересно, как бы инструменты искусственного интеллекта предложили мне его изменить. Ниже приведены результаты, полученные по одному и тому же запросу.

Промпт:

// This function is kind of hard to read - can you make it simpler?  

/* Then I included the function above right here */

chatGPT 4

Во-первых, институциональный выбор. chatGPT от OpenAI использует chatGPT 4:

/*
Certainly! Here's a simplified and refactored version of your Swift function. I've added comments for clarity and improved the readability of the code by separating the removal and addition processes into separate functions:
*/

func updateQuickActionsForCourts() {
    guard !appSettings.quickActionCourtsToAdd.isEmpty || !appSettings.quickActionCourtsToRemove.isEmpty else {
        return
    }
    
    var quickActions = UIApplication.shared.shortcutItems ?? []
    
    // Process removals
    quickActions = removeCourts(from: quickActions)
    
    // Process additions
    quickActions = addCourts(to: quickActions)
    
    // Update quick actions in reverse order and clear settings
    UIApplication.shared.shortcutItems = quickActions.reversed()
    clearCourtSettings()
}

/// Removes courts from the quick actions list based on app settings.
private func removeCourts(from quickActions: [UIApplicationShortcutItem]) -> [UIApplicationShortcutItem] {
    let courtIDsToRemove = Set(appSettings.quickActionCourtsToRemove)
    return quickActions.filter { item in
        guard let courtID = item.userInfo?["courtID"] as? Int64 else { return true }
        return !courtIDsToRemove.contains(courtID)
    }
}

/// Adds courts to the quick actions list based on app settings.
private func addCourts(to quickActions: [UIApplicationShortcutItem]) -> [UIApplicationShortcutItem] {
    var updatedQuickActions = quickActions
    appSettings.quickActionCourtsToAdd.forEach { court in
        let exists = updatedQuickActions.contains { item in
            let courtID = item.userInfo?["courtID"] as? Int64 ?? 0
            return courtID == court.id
        }
        if !exists {
            updatedQuickActions.append(court.quickAction())
        }
    }
    return updatedQuickActions
}

/// Clears the lists of courts to add or remove from app settings.
private func clearCourtSettings() {
    appSettings.quickActionCourtsToAdd.removeAll()
    appSettings.quickActionCourtsToRemove.removeAll()
}

/*
Explanation of Changes:
Guard Statement: A guard statement at the start of the function checks whether any updates are needed, improving readability by reducing nesting.

Separation of Concerns: I extracted the logic for removing and adding courts into separate functions, removeCourts and addCourts. This makes the main function more concise and each piece of functionality easier to maintain.

Filter and Contains: The removal function uses filter and contains to efficiently remove items. This eliminates the need for finding indices and then removing by index, which can introduce errors or require additional adjustments in indexing after each removal.
Function Encapsulation: Moving specific functionality into private helper functions clarifies the main function's flow and isolates each specific task.

Reverse Logic Consolidation: The reversal of the quick actions list is kept at the point where the list is updated in the UIApplication, making the order manipulation more visible.

This refactor should make your function easier to read, maintain, and modify in the future.
*/

Я обнаружил, что chatGPT более многословен в своих ответах. Он не только пишет код, но и пытается объяснить его вам. Этот код хорош, если вы из тех, кто считает, что каждая функция должна быть единственной и не более. Из всех вариантов, когда я возвращаюсь к своему коду (ведь мы всегда возвращаемся к нему, правда?!), этот, пожалуй, ближе всего к тому, как я обычно его правлю.

meta.ai

Новичок на рынке, олицетворяющий подход «если это бесплатно, то вы и есть продукт» — новоиспеченный meta.ai от Meta*. Вот как он рефакторит мой код:

// Here's a simplified version of the function:

func updateQuickActionsForCourts() {
    guard !(appSettings.quickActionCourtsToAdd.isEmpty && appSettings.quickActionCourtsToRemove.isEmpty) else {
        return
    }

    var quickActions = UIApplication.shared.shortcutItems ?? []

    // Remove quick actions
    quickActions.removeAll { item in
        appSettings.quickActionCourtsToRemove.contains(item.userInfo?["courtID"] as? Int64 ?? 0)
    }

    // Add quick actions
    appSettings.quickActionCourtsToAdd.forEach { court in
        if !quickActions.contains(where: { item in
            item.userInfo?["courtID"] as? Int64 == court.id
        }) {
            quickActions.append(court.quickAction())
        }
    }

    UIApplication.shared.shortcutItems = quickActions.reversed()

    appSettings.quickActionCourtsToAdd.removeAll()
    appSettings.quickActionCourtsToRemove.removeAll()
}

/*
This version uses more concise and expressive syntax, such as guard statements, removeAll and contains methods, and more. It should be easier to read and understand. Let me know if you have any questions!
*/

Что мне нравится, так это то, насколько проще его читать. Несмотря на то, что я чаще всего пишу код, похожий на chatGPT 4, я думаю, что смогу легче прочитать то, что написал ИИ от Мета.

Claude от Anthropic

Наконец, есть Claude. Я считаю его последним из «большой тройки», по крайней мере, в моей сфере дейтельности. Должен заметить, что это не лучшая модель Anthropic — это Claude 3 Opus — но в любом случае вот что у меня получилось:

// Here's a simplified version of the updateQuickActionsForCourts function:

func updateQuickActionsForCourts() {
    guard !appSettings.quickActionCourtsToAdd.isEmpty || !appSettings.quickActionCourtsToRemove.isEmpty else {
        return
    }

    var quickActions = UIApplication.shared.shortcutItems ?? []

    // Remove unwanted quick actions
    quickActions = quickActions.filter { action in
        guard let courtID = action.userInfo?["courtID"] as? Int64 else {
            return true
        }
        return !appSettings.quickActionCourtsToRemove.contains(courtID)
    }

    // Add new quick actions
    let existingCourtIDs = quickActions.compactMap { $0.userInfo?["courtID"] as? Int64 }
    let newQuickActions = appSettings.quickActionCourtsToAdd
        .filter { !existingCourtIDs.contains($0.id) }
        .map { $0.quickAction() }
    quickActions.append(contentsOf: newQuickActions)

    UIApplication.shared.shortcutItems = quickActions
    appSettings.quickActionCourtsToAdd.removeAll()
    appSettings.quickActionCourtsToRemove.removeAll()
}

/*
Here are the main changes:

- The early return is moved to the beginning of the function to avoid unnecessary work if there are no actions to add or remove.

- The removal of unwanted quick actions is done using the filter method, which creates a new array containing only the elements that satisfy the condition.

- The addition of new quick actions is done by first creating an array of existing court IDs, then filtering the appSettings.quickActionCourtsToAdd array to remove any courts that already have a quick action, and finally mapping the remaining courts to their corresponding quick actions.

- The append(contentsOf:) method is used to add the new quick actions to the existing array in a single operation.

- The reversed() call has been removed since it is unnecessary.

These changes make the code more concise and easier to read, while preserving the original functionality.
*/

Неплохо, что, как и chatGPT 4, модель склонна подробно объяснять, что именно она изменила и почему она это сделала. И, как и в Meta, решение по-прежнему находится в рамках одной функции, но значительно упрощено.

Заключительные мысли

Я не выношу никакого вердикта в этом посте, кроме как… интересно посмотреть, как большие языковые модели рассуждают о коде. Например, все три модели быстро указали на ранний оператор guard. И каждая из них склонна опираться на особенности языка, такие как функциональные аспекты Swift. Как и должно быть, я полагаю.

Так к чему я пришел?

Я просто оставил свою оригинальную, уродливую функцию и написал этот пост 😇.

До следующего раза ✌️.

Источник

Exit mobile version