Kotlin - Guava's Iterables.transform equivalent? - arraylist

Please look at this Java code:
calendarEvents = Lists.newArrayList(Iterables.transform(
wastageSchedule, item -> new BaseCalendarEvent(
item.getWastageTypeName(),
item.getWastageTypeName(),
item.getLocation(),
ContextCompat.getColor(this, R.color.colorWastageItem),
item.getStartDate(),
item.getEndDate(),
true
)
));
It just transforms ArrayList<CalendarEvent> into ArrayList<BaseCalendarEvent>. Is there any equivalent to it in Kotlin? I looked into Kotlin documentation, but I did not find anything like transform, can you provide any tip?

Kotlin has map extension function on Iterables. E. g.
calendarEvents = wastageSchedule.map { item ->
BaseCalendarEvent(...)
}

Related

Better code for mapping json objects with AWS Dynamo AttributeValues in Kotlin

I am using below code to map the json objects with AWS Dynamo DB attributes but I am not sure whether this will be having any performance issue or not? Please let me know if we have any other better way to achieve it.
I have list of maps and want store them in Dynamo. I am using AWS SDK V2 and Kotlin for it.
//items in model class
var items: List<Map<String, Any>>? = null
val itemValues = mutableMapOf<String, AttributeValue>()
itemValues.put("items", fromL(
order.items?.map { attributes ->
fromM(
attributes.mapValues { attribute ->
fromS(attribute.value.toString())
}
)
}
))
Above mentioned code is working but I want to know if there is any better way to do this.

Configure array/object indentation for YAML in Jackson

I'm trying to generate a YAML file from an input Map I'm using Jackson and the YamlFactory utility provided by Jackson to do so. I'm attempting to configure the indentation property for the YAML output, but it doesn't seem like that's being respected at all.
Here's how my code looks like:
fun getSdkResultAsGenericObject(sdkResult: Any?): Any? {
if (sdkResult == null) {
return null
}
var genericObj: Any?
val stringified = genericSdkObjectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(sdkResult)
.replace("\n", "")
val isArray = stringified.startsWith("[")
genericObj = if (isArray) {
genericSdkObjectMapper.readValue(stringified, List::class.java)
} else {
genericSdkObjectMapper.readValue(stringified, LinkedHashMap::class.java)
}
val defaultYaml = resultYamlMapper.writerWithDefaultPrettyPrinter().writeValueAsString(genericObj )
}
The declaration of the resultYamlMapper is like this:
val yamlFactory = YAMLFactory()
.configure(YAMLGenerator.Feature.SPLIT_LINES, false)
.configure(YAMLGenerator.Feature.INDENT_ARRAYS, true)
val resultYamlMapper = ObjectMapper(YamlFactory())
The documentation says that the INDENT_ARRAYS feature uses 2 spaces by default. I'm trying to understand how I can configure that? I need 4 spaces in the resultant YAML. I tried setting a pretty print writer:
val yamlFactory = YAMLFactory()
.configure(YAMLGenerator.Feature.SPLIT_LINES, false)
.configure(YAMLGenerator.Feature.INDENT_ARRAYS, true)
val resultYamlMapper = ObjectMapper(YamlFactory())
val arrayIndenter = DefaultIndenter(" ", DefaultIndenter.SYS_LF)
val objectIndenter = DefaultIndenter(" ", DefaultIndenter.SYS_LF)
resultYamlMapper.setDefaultPrettyPrinter(DefaultPrettyPrinter().withObjectIndenter(objectIndenter).withArrayIndenter(arrayIndenter))
But this doesn't seem to be respected at all. Any thoughts? Or does Jackson not let you configure the indentation at all?
The docs show that the PrettyPrinter interface is only for the JsonGenerator.
If you want to customize your YAML output, you have to use the SnakeYAML API directly (which is used by Jackson for YAML processing). SnakeYAML has similar features to Jackson and there is little reason to use Jackson if you only want to process YAML. Most importantly, it lets you configure YAML formatting.

How to get all properties with the ids

I'm new to all the graph database stuff and I'm having a hard time with some basic queries.
I'm using Gremlin with Kotlin to connect to AWS Neptune.
I want to get all my vertex properties including the Id.
I have added an vertex with:
g.addV("foo")
.property("name", "Foo 1")
.next()
And to retrieve the properties I have tried:
g.V()
.hasLabel("foo")
.valueMap<String>()
.by(unfold<String>())
.forEach {
// val name = it["name"] -> works great!
// val id = it["id"] -> doesn't exist
}
In this first approach I get a map for each item but this map does not contain the ID.
g.V()
.hasLabel("foo")
.forEach {
// it is an ReferenceVertex that has an ID!
val name = it.property<String>("name") // This returns an EmptyVertexProperty, so I can't read the name
}
I'm using
<dependency>
<groupId>org.apache.tinkerpop</groupId>
<artifactId>gremlin-driver</artifactId>
<version>3.4.4</version>
</dependency>
Bonus question
I couldn't figure out (nor find in the documentation) what the generics on valueMap and unfold method do. Kotlin does not allow me to ommit them (as I have seem in some java code...?), but changing them to Int, for instance, changes nothing in the outcome for these examples... So what is it for? D:
Thanks in advance!
If you want to get the Id with all the other properties you need to run valueMap().with(WithOptions.tokens) or you can use elementMap().

KotlinPoet - Generate Koin module

I'm new to KotlinPoet and I cannot find how to create the following Koin module statement:
internal val apiModules = module {
single<Name1> { get<Retrofit>().create(Name1::class.java) }
single<Name2> { get<Retrofit>().create(Name2::class.java) }
}
directly into a Kotlin file (no wrapper class)
I have been playing around with PropertySpec and CodeBlock but I don't know how to import Koin DSL or how to reference those imported classes in the code generation. I was also unable to generate the code by pure string generation.
You need to generate the file using FileSpec and add a PropertySpec for the module
It shold look similar to this
val moduleClassName = ClassName("org.koin.core.module.Module", "Module") //This will take care of the import
val moduleMemberName = MemberName("org.koin.dsl.module", "module") //This will take care of the import
val moduleInitilizerCodeBlock =
CodeBlock.Builder()
.beginControlFlow("%M", moduleMemberName) //This will take care of the {} and indentations
.addStatment(ADD ANOTHER CODE BLOCK SIMNILAR TO THIS FOR THE SINGLE/FACTORY)
.endControlFlow()
.build()
val module = PropertySpec.builder("YOUR MODULE NAME", moduleClassName)
.initializer(moduleInitilizerCodeBlock)
.build()
FileSpec.Builder("FILE PACKAGE", "FILE NAME")
.addProperty(module)
.build()
This is not full code but it should point you in the right direction.
Side note: I might me wrong about specific namings but again it should be enough

Kotlin Builder vs Constructor

I'm pretty new to Kotlin, and I've come across both of these representations:
Car(name = "CarName")
and
car {
name = "CarName"
}
Is there any guidelines about when which one should be used? The docs don't seem to be too clear on this.
The second snippet is an example of how you could build a DSL for your domain. For simple cases like this, it is a bit overkill to create a DSL, but when your objects get larger it might be cleaner to design a DSL.
In fact, using the DSL style to create simple instances might even be confusing.
For example, the documentation on DSLs shows the following code:
fun result(args: Array<String>) =
html {
head {
title {+"XML encoding with Kotlin"}
}
body {
h1 {+"XML encoding with Kotlin"}
p {+"this format can be used as an alternative markup to XML"}
// an element with attributes and text content
a(href = "http://kotlinlang.org") {+"Kotlin"}
// mixed content
p {
+"This is some"
b {+"mixed"}
+"text. For more see the"
a(href = "http://kotlinlang.org") {+"Kotlin"}
+"project"
}
p {+"some text"}
// content generated by
p {
for (arg in args)
+arg
}
}
}
This is an excellent example of when you could use a DSL: The syntax enables a clean structure of how you create your models. Anko for another provides a DSL to defines UI's.