I have data in the following format
ArrayList<Map.Entry<String,ByteString>>
[
{"a":[a-bytestring]},
{"b":[b-bytestring]},
{"a:model":[amodel-bytestring]},
{"b:model":[bmodel-bytestring]},
]
I am looking for a clean way to transform this data into the format (List<Map.Entry<ByteString,ByteString>>
) where the key
is the value of a
and value
is the value of a:model
.
Desired output
List<Map.Entry<ByteString,ByteString>>
[
{[a-bytestring]:[amodel-bytestring]},
{[b-bytestring]:[bmodel-bytestring]}
]
I assume this will involve the use of filters or other map operations but am not familiar enough with Kotlin yet to know this
CodePudding user response:
It's not possible to give an exact, tested answer without access to the ByteString
class — but I don't think that's needed for an outline, as we don't need to manipulate byte strings, just pass them around. So here I'm going to substitute Int
; it should be clear and avoid any dependencies, but still work in the same way.
I'm also going to use a more obvious input structure, which is simply a map:
val input = mapOf("a" to 1,
"b" to 2,
"a:model" to 11,
"b:model" to 12)
As I understand it, what we want is to link each key without :model
with the corresponding one with :model
, and return a map of their corresponding values.
That can be done like this:
val output = input.filterKeys{ !it.endsWith(":model") }
.map{ it.value to input["${it.key}:model"] }.toMap()
println(output) // Prints {1=11, 2=12}
The first line filters out all the entries whose keys end with :model
, leaving only those without. Then the second creates a map from their values to the input values for the corresponding :model
keys. (Unfortunately, there's no good general way to create one map directly from another; here map()
creates a list of pairs, and then toMap()
creates a map from that.)
I think if you replace Int
with ByteString
(or indeed any other type!), it should do what you ask.
The only thing to be aware of is that the output is a Map<Int, Int?>
— i.e. the values are nullable. That's because there's no guarantee that each input key has a corresponding :model
key; if it doesn't, the result will have a null value. If you want to omit those, you could call filterValues{ it != null }
on the result.
However, if there's an ‘orphan’ :model
key in the input, it will be ignored.