Sorry for the poor title but it is rather hard to describe my use case in a short sentence.
Context
I have the following model:
typealias Identifier = String
data class Data(val identifier: Identifier,
val data1: String,
val data2: String)
And I have three main data structures in my use case:
A Set of Identifiers that exist and are valid in a given context. Example:
val existentIdentifiers = setOf("A-1", "A-2", "B-1", "B-2", "C-1")
A Map that contains a List of Data objects per Identifier. Example:
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"))
)
A List of Lists that group together the Identifiers that should share the same List<Data> (each List includes always 2 Identifiers). Example
val identifiersWithSameData = listOf(listOf("A-1", "A-2"), listOf("B-1", "B-2"))
Problem / Use Case
The problem that I am trying to tackle stems from the fact that dataPerIdentifier might not contain all identifiersWithSameData given that existentIdentifiers contains such missing Identifiers. I need to add those missing Identifier to dataPerIdentifier, copying the List<Data> already in there.
Example
Given the data in the Context section:
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)]
The desired outcome is to update dataPerIdentifier so that it includes:
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)]
The reason is that existentIdentifiers contains A-2 that is missing in the initial dataPerIdentifier Map. B-2 is also missing in the initial dataPerIdentifier Map but existentIdentifiers does not contain it, so it is ignored.
Possible solution
I have already a working code (handleDataForMultipleIdentifiers() method is the one doing the heavy lifting), but it does not feel to be the cleanest or easiest to read:
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)
So my question is: how can I do this in a simpler way?
If identifiersWithSameData always contains 2 identifiers per item then it should not really be a list of lists, but rather a list of pairs or dedicated data classes. And if you convert this data structure into a map like this:
val identifiersWithSameData = mapOf("A-1" to "A-2", "A-2" to "A-1", "B-1" to "B-2", "B-2" to "B-1")
The the whole solution is pretty simple:
existentIdentifiers.associateWith {
dataPerIdentifier[it] ?: dataPerIdentifier[identifiersWithSameData[it]!!]!!
}
I'm not sure about both !!, for example I don't know if it is guaranteed that identifier existing in existentIdentifiers exists in identifiersWithSameData as well. You may need to tune this solution a little.
I'm using Spring's HATEOAS repo:
#RepositoryRestResource(collectionResourceRel = "equipment", path = "equipment")
interface EquipmentRepository : PagingAndSortingRepository<Equipment, Int>
Here's my domain object:
#Entity
data class Equipment(
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
val id: Int?,
val serialNumber: String?,
val modelNumber: String,
val make: String,
val model: String,
val year: Int,
val purchaseDate: Date,
val warrantyEnds: Date,
val cost: Double
)
I'm using cURL and Postman to create equipment and it's all good. If I use PATCH for a partial update the query updates the object - if I use the same URL and same data for PUT nothing is updated but I get a 200 response (and the old object) in postman.
How come I can PATCH http://localhost:8080/equipment/1 works but a PUT with the same data and same endpoint returns 200 but does not update the data?
No errors on the server-side on the console/logs, or any indication as to why I'm getting a 200 and no update...
I am using Kotlin, if it matters...
Try change val to var, i had the same problem and this should help.
how do I group by "group" when located in the sub model?
i tried do this, but it error result
mtop.groupBy { it.sub[0].group }
this my code
// my model
data class mTop(val kategori : String, val sub : ArrayList<mSub>)
data class mSub(val id_menu : String, val nama_menu : String, val gambar : String, val group : String)
// my activity
val mtop: ArrayList<mTop> = ArrayList()
val msub: ArrayList<mSub> = ArrayList()
mtop.add(mTop(header, msub))
sorry I often ask on this forum but never helped others, because I'm a beginner and my English is bad. Thank You
mtop.groupBy { it.sub[0].group }
The error you are getting is because sub is empty and you are trying to get the first element.
What you can probably do is to do a filter before trying to groupBy:
mtop.filter{it.sub.isNotEmpty()}.groupBy{it.sub[0].group}
In Kotlin, how to get the raw value of the String?
For example,
val value: String = "Adrian"
Expected result:
"Cannot find value: Adrian"
I am coming from Swift and I know in swift it works like this
let value: String = "Adrian"
print("Cannot find \(string.description): \(value)")
Another example in Swift,
let a: String = "b"
print("\(a.description) = \(a)"
///prints "a = b"
Im guessing a String extension is needed given I read the Kotlin String documentation and seems none of the choices provides the expected result.
A simple problem but I really can't solve it:(
This might help you. For this you have to use Kotlin reflection:
Example:
data class Person(val name:String)
fun main(){
val person = Person("Birju")
val prop = person::name
println("Property Name: ${prop.name}")
println("Property Value: ${prop.get()}")
}
How about
println("value :$value")
You don't need concatination operator(+) to concat strings in kotlin
I parsed a json string to the following object structure using gson:
data class Base (
val expand: String,
val startAt: Long,
val maxResults: Long,
val total: Long,
val issues: List<Issue>
)
data class Issue (
val expand: String,
val id: String,
val self: String,
val key: String,
val fields: Fields
)
data class Fields (
val summary: String,
val issuetype: Issuetype,
val customfield10006: Long? = null,
val created: String,
val customfield11201: String? = null,
val status: Status,
val customfield10002: Customfield10002? = null,
val customfield10003: String? = null
)
Everything works fine and also the object model is correct, because I can access each element of the object.
However, I encountered the problem that I dont know how to get a list of all field-elements. Right now, I have only figured out how to access one item (by using an index and get()-function):
val baseObject = gson.fromJson(response, Base::class.java)
val fieldsList = baseObject.issues.get(0).fields
I actually want to have a list of all field elements and not just one. Is there a gson function allowing me to do that? I couldn't find anything about it in the gson documentation for java.
You don't have to look for some gson function when you've already created a baseObject. You just need to get from each issue it's fields and you can use a map function to achieve this, it will convert each issue to a new type so you can get issue fields there
val fieldFromAllIssues: List<Fields> = baseObject.issues.map { it.fields }
it in this context is a one issue. More explanation about it is here