Можно ли упростить этот код кастлинга? - PullRequest
1 голос
/ 29 мая 2019

У нас есть какой-то код для стороннего SDK, который возвращает «Any?». И мы должны разыграть его (если он разыгрывает и анализирует). Поскольку наши приведения являются общими, я не смог понять, как это упростить, не написав 5 приведения. Это кажется намного проще в Swift. Есть ли лучший способ сделать эти броски?

private fun parseOrganizations(payload: Any?): List<UserOrganization> {
        val organizations = mutableListOf<UserOrganization>()
        payload?.let { userData ->
            if (userData is Map<*, *>) {
                val orgJsonList = userData["organizations"]
                if (orgJsonList is List<*>) {
                    for (jsonMap in orgJsonList) {
                        if (jsonMap is Map<*, *>) {
                            val id = jsonMap["id"] as? String
                            val name = jsonMap["name"] as? String
                            val role = jsonMap["role"] as? String
                            val isActive = jsonMap["isActive"] as? Boolean
                            val isVerified = jsonMap["isVerified"] as? Boolean
                            if (id != null && name != null && role != null && isActive != null && isVerified != null) {
                                val org = UserOrganization(id, name, role, isActive, isVerified)
                                organizations.add(org)
                            }
                        }
                    }
                }
            }
        }
        return organizations
    }

Спасибо, ребята.

1 Ответ

2 голосов
/ 29 мая 2019

Вы можете избежать большого количества вложенных if, просто изменив его на ?.let и for на map. Код в этом случае будет плоским и читабельным

fun parseOrganizations(payload: Any?) {
    payload
        ?.let { it as? Map<*, *> }
        ?.let { it["organizations"] as? List<*> }
        ?.mapNotNull { if (it is Map<*, *>) UserOrganization.fromMap(it) else null }
        ?.map { organizations.add(it) }
}

Но мы должны иметь дело с созданием UserOrganization из Map, содержащего сведения об организации. Если честно, я не смог придумать действительно изящный способ. Но лучше создать внешнюю функцию или что-то вроде этого, чтобы инкапсулировать запасную логику:

class UserOrganization(
    val id: String,
    val name: String,
    val role: String,
    val isActive: Boolean,
    val isVerified: Boolean
){
    companion object {
        fun fromMap(org: Map<*,*>): UserOrganization? =
            if (org.keys.containsAll(listOf("id", "name", "role", "isActive", "isVerified"))) {
                UserOrganization(
                    id = org["id"] as? String ?: "Unknown Id",
                    name = org["name"] as? String ?: "Unknown name",
                    role = org["role"] as? String ?: "Unknown role",
                    isActive = org["isActive"] as? Boolean ?: false,
                    isVerified = org["isVerified"] as? Boolean ?: false
                )
            } else null
    }
}

Не могу поспорить, что это работает на 100% правильно, но я думаю, что смогу показать идею.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...