【发布时间】:2022-01-18 05:04:07
【问题描述】:
很抱歉标题不好,但很难用一句话来描述我的用例。
上下文
我有以下型号:
typealias Identifier = String
data class Data(val identifier: Identifier,
val data1: String,
val data2: String)
我的用例中有三个主要的数据结构:
-
Set中的Identifiers 存在且在给定上下文中有效。示例:
val existentIdentifiers = setOf("A-1", "A-2", "B-1", "B-2", "C-1")
- 一个
Map,每个Identifier包含List个Data对象。示例:
val dataPerIdentifier: Map<Identifier, List<Data>> = mapOf(
"A-1" to listOf(Data("A-1", "Data-1-A", "Data-2-A"), Data("A-1", "Data-1-A", "Data-2-A")),
"B-1" to listOf(Data("B-1", "Data-1-B", "Data-2-B")),
"C-1" to listOf(Data("C-1", "Data-1-C", "Data-2-C"))
)
-
List的Lists 将应共享相同List<Data>的Identifiers 组合在一起(每个List始终包含 2 个Identifiers)。示例
val identifiersWithSameData = listOf(listOf("A-1", "A-2"), listOf("B-1", "B-2"))
问题/用例
我试图解决的问题源于dataPerIdentifier 可能不包含所有identifiersWithSameData,因为existentIdentifiers 包含这样的缺失Identifiers。我需要将那些缺少的Identifier 添加到dataPerIdentifier,复制那里已经存在的List<Data>。
示例
鉴于上下文部分中的数据:
A-1=[Data(identifier=A-1, data1=Data-1-A, data2=Data-2-A),
Data(identifier=A-1, data1=Data-1-A, data2=Data-2-A)],
B-1=[Data(identifier=B-1, data1=Data-1-B, data2=Data-2-B)],
C-1=[Data(identifier=C-1, data1=Data-1-C, data2=Data-2-C)]
期望的结果是更新dataPerIdentifier,使其包括:
A-1=[Data(identifier=A-1, data1=Data-1-A, data2=Data-2-A),
Data(identifier=A-1, data1=Data-1-A, data2=Data-2-A)],
B-1=[Data(identifier=B-1, data1=Data-1-B, data2=Data-2-B)],
C-1=[Data(identifier=C-1, data1=Data-1-C, data2=Data-2-C)],
A-2=[Data(identifier=A-2, data1=Data-1-A, data2=Data-2-A),
Data(identifier=A-2, data1=Data-1-A, data2=Data-2-A)]
原因是existentIdentifiers 包含A-2,而初始dataPerIdentifier Map 中缺少该A-2。 B-2 在最初的dataPerIdentifier Map 中也缺少,但existentIdentifiers 不包含它,因此被忽略。
可能的解决方案
我已经有一个工作代码(handleDataForMultipleIdentifiers() 方法是最繁重的方法),但感觉不是最干净或最容易阅读的代码:
fun main(args: Array<String>) {
val existentIdentifiers = setOf("A-1", "A-2", "B-1", "C-1")
val dataPerIdentifier: Map<Identifier, List<Data>> = mapOf(
"A-1" to listOf(Data("A-1", "Data-1-A", "Data-2-A"), Data("A-1", "Data-1-A", "Data-2-A")),
"B-1" to listOf(Data("B-1", "Data-1-B", "Data-2-B")),
"C-1" to listOf(Data("C-1", "Data-1-C", "Data-2-C"))
)
val identifiersWithSameData = listOf(listOf("A-1", "A-2"), listOf("B-1", "B-2"))
print("Original Data")
println(dataPerIdentifier)
print("Target Data")
println(dataPerIdentifier.handleDataForMultipleIdentifiers(identifiersWithSameData, existentIdentifiers))
}
fun Map<Identifier, List<Data>>.handleDataForMultipleIdentifiers(identifiersWithSameData: List<List<Identifier>>, existentIdentifiers: Set<Identifier>)
: Map<Identifier, List<Data>> {
val additionalDataPerIdentifier = identifiersWithSameData
.mapNotNull { identifiersList ->
val identifiersWithData = identifiersList.find { it in this.keys }
identifiersWithData?.let { it to identifiersList.minus(it).filter { it in existentIdentifiers } }
}.flatMap { (existentIdentifier, additionalIdentifiers) ->
val existentIdentifierData = this[existentIdentifier].orEmpty()
additionalIdentifiers.associateWith { identifier -> existentIdentifierData.map { it.copy(identifier = identifier) } }.entries
}.associate { it.key to it.value }
return this + additionalDataPerIdentifier
}
typealias Identifier = String
data class Data(val identifier: Identifier,
val data1: String,
val data2: String)
所以我的问题是:我怎样才能以更简单的方式做到这一点?
【问题讨论】:
标签: kotlin