miqbaldc
11/18/2021, 8:43 AM<deeplink scheme>://jobs?category_id=asdf&employment_type=FULLTIME
into a query parameter (what I can think of atm was map):
mapOf(
"category_id" to "asdf",
"employment_type" to "FULLTIME"
)
my code attempts in 🧵LeoColman
11/24/2021, 1:07 AMvar millis = 123L
var i = 0
buildList<Pair<TimeUnit, Long>> {
add(Year to (millis / MillisInYear))
millis -= (get(i++).second * MillisInYear)
add(Month to (millis / MillisInMonth))
millis -= (get(i++).second * MillisInMonth)
add(Day to (millis / MillisInDay))
millis -= (get(i++).second * MillisInDay)
add(Hour to (millis / MillisInHour))
millis -= (get(i++).second * MillisInHour)
add(Minute to (millis / MillisInMinute))
millis -= (get(i++).second * MillisInMinute)
add(Second to (millis / 1_000))
millis -= (get(i++).second * 1_000)
add(Millisecond to millis)
}
This code is used to make a timer/counter (picture)
However, it's very ugly as it is. How can I enhance this?Sergio C.
11/30/2021, 6:23 PMvar qtdTotal = 0.0f
val partition = response?.partition { it.uidCaracteristica != 0 }
val uidGroup = partition?.first?.groupBy { it.produto }?.toMutableMap() ?: mutableMapOf()
uidGroup[0] = partition?.second ?: listOf()
uidGroup.forEach { (key, uidsList) ->
if (key == 0) {
uidsList.forEach { stk ->
addRow(
stk.description ?: "", "", "", "",
extraInfo = listOf(
stk.produto.toString(),
stk.description ?: "",
stk.codbarras ?: "",
stk.referencia ?: ""
)
)
qtdTotal += stk.stock ?: 0.0f
}
} else {
val caracteristicas = uidsList.map {
ReportsDataset.Row(
it.caracteristica ?: "",
it.stkmin?.toString() ?: "",
it.stkmax?.toString() ?: "",
it.stock?.toString() ?: "",
extraInfo = listOf(it.uidCaracteristica?.toString() ?: "")
)
}
val stk = uidsList.first()
addRow(
stk.description ?: "", "", "", "",
extraRows = caracteristicas,
extraInfo = listOf(
stk.produto.toString(),
stk.description ?: "",
stk.codbarras ?: "",
stk.referencia ?: ""
)
)
qtdTotal += stk.stock ?: 0.0f
}
}
miqbaldc
12/13/2021, 12:07 PMCoroutineDispatcher
and returns Flow<T>
or suspend
(return T
) is enough?
abstract class FlowUseCase<out T, in Params> constructor(
private val threadExecutor: CoroutineDispatcher
) {
protected abstract fun execute(params: Params? = null): Flow<T>
open operator fun invoke(params: Params? = null): Flow<T> =
execute(params).flowOn(threadExecutor)
}
What implementation did you folks use, would love to know the pros n consSlackbot
01/06/2022, 10:08 PMchansek
01/28/2022, 6:19 AMval adminOf = user.roles
.filter { it.isAdmin() }
.map { it.entityId to it.entity }
.toMap()
val serviceProviderOf = user.roles
.filter { it.isServiceProvider() }
.map { it.entityId to it.entity }
.toMap()
myanmarking
01/28/2022, 7:45 PMhho
02/02/2022, 11:16 AMreturn
even if some branches don't return anything? I think I might like the version with multiple return statements better in this case…
return if (someExpr) {
doSomeStuff()
someThing
} else if (otherExpr) {
doOtherStuff()
otherThing
} else {
throw RuntimeException("uh oh")
}
miqbaldc
02/03/2022, 1:55 PM1️⃣orpreconditions
for this case, maybe any references?throw
suspend fun updatePushToken(newPushToken: String): Result<String> = invoke {
require(newPushToken.isNotEmpty()) { "Push token is required to not empty" }
kotlin.runCatching { repository.agentUpdatePushToken(newPushToken = newPushToken) }
}
or
2️⃣
suspend fun updatePushToken(newPushToken: String): Result<String> = invoke {
if (newPushToken.isEmpty()) {
throw IllegalArgumentException("Push token is required to not empty")
}
kotlin.runCatching { repository.agentUpdatePushToken(newPushToken = newPushToken) }
}
jwass
02/03/2022, 2:03 PMdata class Thing(val x: Int, val y: Int, val ignoreMe: String)
which I want to put in a set to perform set operations, but ignore certain fields for the purpose of set comparison. i.e. only considering a subset of fields for equality comparisons.
val x = setOf(Thing(5, 5, "Hello"), Thing(10, 6, "Goodbye"), Thing(100, 3, "Zzzz"))
val y = setOf(Thing(5, 5, "Baz"), Thing(10, 6, "Goodbye"))
val result = x.minus(y)
-> result = setOf(Thing(100, 3, "Zzzz")) // because Thing(5, 5, "Hello") is considered equal to Thing(5, 5, "Baz")
In reality the data classes are a bit richer, about 6 fields.
I thought I could build a sorted set with a custom comparator, but that requires implementing a sorting on the data classes when I only really want a custom equality for that set.
I only want this custom equality behaviour in one context, so it’s not appropriate to actually re-implement equals
etc on the data classes directly.
Any ideas about if there’s a simple way to achieve this?
(edit - found a nice idea on stack overflow - just wrap the objects in a special purpose class)therealbluepandabear
02/07/2022, 3:56 AMFileHelperUtilities
class in Kotlin to help with:
• Saving a Bitmap as PNG/JPG
• Opening an image from a URI with an Intent
Code:
bject FileHelperUtilities {
fun saveBitmapAsImage(compressionOutputQuality: Int, compressionFormat: Bitmap.CompressFormat, onTaskFinished: (OutputCode, File) -> Unit, context: Context) {
// Thanks to <https://stackoverflow.com/users/3571603/javatar> on StackOverflow - quite a bit of the code is based off of their solution
var outputCode = OutputCode.SUCCESS
val pathData = "image/jpeg"
val outputName = if (compressionFormat == Bitmap.CompressFormat.PNG) "$projectTitle.png" else "$projectTitle.jpg"
val environmentRoot = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).toString()
val directory = File(environmentRoot)
directory.mkdirs()
val file = File(directory, outputName)
try {
val outputStream = FileOutputStream(file)
val bitmapToCompress = outerCanvasInstance.fragmentHost.drawToBitmap()
bitmapToCompress.compress(compressionFormat, compressionOutputQuality, outputStream)
outputStream.close()
} catch (exception: Exception) {
outputCode = OutputCode.FAILURE
} finally {
onTaskFinished(outputCode, file)
}
MediaScannerConnection.scanFile(context, arrayOf(file.path), arrayOf(pathData), null)
}
fun openImageFromUri(uri: Uri, onTaskFinished: (OutputCode) -> Unit, context: Context) {
var outputCode = OutputCode.SUCCESS
val intentAction = Intent.ACTION_VIEW
val type = "image/*"
val intent = Intent()
intent.action = intentAction
intent.setDataAndType(uri, type)
try {
context.startActivity(intent)
} catch (exception: Exception) {
outputCode = OutputCode.FAILURE
} finally {
onTaskFinished(outputCode)
}
}
}
Here it is in use:
package com.realtomjoney.pyxlmoose.customviews.pixelgridview
import android.graphics.Bitmap
import android.net.Uri
import com.realtomjoney.pyxlmoose.activities.canvas.projectTitle
import com.realtomjoney.pyxlmoose.enums.OutputCode
import com.realtomjoney.pyxlmoose.extensions.SnackbarDuration
import com.realtomjoney.pyxlmoose.extensions.showSnackbar
import com.realtomjoney.pyxlmoose.extensions.showSnackbarWithAction
import com.realtomjoney.pyxlmoose.utility.FileHelperUtilities
import java.io.File
lateinit var file: File
fun PixelGridView.extendedSaveAsPNG() {
FileHelperUtilities.saveBitmapAsImage(90, Bitmap.CompressFormat.PNG, { outputCode, _file ->
if (outputCode == OutputCode.SUCCESS) {
file = _file
showSnackbarWithAction("Successfully saved $projectTitle as PNG", SnackbarDuration.MEDIUM, "View") {
FileHelperUtilities.openImageFromUri(Uri.fromFile(file), { outputCode ->
if (outputCode == OutputCode.FAILURE) {
showSnackbar("Error trying to view file", SnackbarDuration.DEFAULT)
}
}, context)
}
} else {
showSnackbar("Error saving $projectTitle as PNG", SnackbarDuration.DEFAULT)
}
}, context)
}
Mark
02/23/2022, 8:01 AM/**
* usage: val regex by "foo".lazyRegex(RegexOption.IGNORE_CASE)
* instead of:
* val regex by lazy { "foo".toRegex(RegexOption.IGNORE_CASE) }
* or:
* val regex = "foo".toRegex(RegexOption.IGNORE_CASE)
*/
fun String.lazyRegex(option: RegexOption? = null): Lazy<Regex> =
lazy {
if (option == null)
toRegex()
else
toRegex(option)
}
So here, if you already have a bunch of properties like:
val regex = "foo".toRegex()
you can very easily convert to:
val regex by "foo".lazyRegex()
therealbluepandabear
02/26/2022, 3:46 AMimport java.util.UUID
enum class Color {
RED, ORANGE, YELLOW, GREEN, BLUE, PURPLE, TRANSPARENT
}
interface Shape {
val name: String
val uuid: UUID
get() = UUID.randomUUID()
val width: Int
val height: Int
val fillColor: Color
val strokeThickness: Int
val strokeColor: Color
fun draw()
fun erase()
}
class Square(
override val width: Int,
override val height: Int,
override val fillColor: Color,
override val strokeThickness: Int,
override val strokeColor: Color
) : Shape {
init {
if (width != height) {
throw IllegalArgumentException("Length must be equal to width.")
}
}
override val name = "Square"
override fun draw() {
println("$name has been drawn.")
}
override fun erase() {
println("$name has been erased.")
}
}
class Rectangle(
override val width: Int,
override val height: Int,
override val fillColor: Color,
override val strokeThickness: Int,
override val strokeColor: Color
) : Shape {
override val name = "Rectangle"
override fun draw() {
println("$name has been drawn.")
}
override fun erase() {
println("$name has been erased.")
}
}
class Canvas(
private val width: Int,
private val height: Int,
private val shapeData: MutableList<Shape>
) {
init {
for (shape in shapeData) {
if (shape.width > this.width || shape.height > this.height) {
throw IllegalArgumentException("Shape of ${shape.uuid} is too large.")
}
}
}
fun eraseContents() {
for (shape in shapeData) {
shape.erase()
}
}
fun drawContents() {
for (shape in shapeData) {
shape.draw()
}
}
}
KV
03/02/2022, 2:11 PMdata class ViewState(
var startDateTime: LocalDateTime? = null,
var endDateTime: LocalDateTime? = null,
var totalBreakDuration: Duration? = null,
var onEditClick: () -> Unit = {}
) {
fun totalDuration() = startDateTime?.let { startDateTime ->
endDateTime?.let { endDateTime ->
Duration.between(startDateTime, endDateTime)
}
}
fun workDuration() = totalDuration()?.minus(totalBreakDuration!!)
}
I have stateImplementation like Below:
state.startDateTime?.let {
ViewItemState(
label = "label",
value = it.format(ISO_LOCAL_DATE)
)
}?.let(binding.dateItem::setupWithState)
-----------------------------------------------------------------
state.startDateTime?.let {
ViewItemState(
label = "label"
value = it.format(ISO_LOCAL_TIME)
)
}?.let(binding.startTimeItem::setupWithState)
-----------------------------------------------------------------------------
state.endDateTime?.let {
ViewItemState(
label = "label",
value = it.format(ISO_LOCAL_TIME)
)
}?.let(binding.endTimeItem::setupWithState)
-----------------------------------------------------------------------------
state.totalDuration()?.let { DurationFormat().format(it) }?.let {
ViewItemState(
label = "label",
value = it
)
}?.let(binding.totalTimeItem::setupWithState)
-----------------------------------------------------------------------------
state.totalBreakDuration?.let { DurationFormat().format(it) }?.let {
ViewItemState(
label = "label,
value = it
)
}?.let(binding.totalBreakTimeItem::setupWithState)
-----------------------------------------------------------------------------
state.workDuration()?.let { DurationFormat().format(it) }?.let {
ViewItemState(
label = "label",
value = it
)
}?.let(binding.workTimeItem::setupWithState)
Colton Idle
03/16/2022, 2:40 AM[FIRST]..[LAST]
Notice the two dots are supposed to show that there are two spaces. What's a convenient way of only having a single space?
private fun Person.prettyPrint() =
"${this.data.firstName} ${this.data.middleName} ${this.data.lastName}"
marcinmoskala
03/23/2022, 11:43 AMSzymon Jeziorski
03/27/2022, 11:55 AMabstract class SampleModifications {
protected fun helper1(...) [...]
protected fun SampleField.helper2(...) [...]
}
helpers usage:
SampleMapper.kt
object SampleMapper : SampleModifications() {
fun Sample.toSomethingElse() = [...] // calling helper1 from SampleModifications inside
[...]
}
extensions usage:
import [...].SampleMapper.toSomethingElse
[...]
sampleRepository.findByIdOrNull(id)?.toSomethingElse()
This works fine and does what I want but declaring abstract classes for such use case seems like overkill for me so wondering if I could achieve the same cleaner or maybe more idiomatic, how would you approach it?Mark
04/01/2022, 9:19 AMval getValuesForKey: (String) -> Set<String> =
object : (String) -> Set<String> {
val map = mutableMapOf<String, Set<String>>()
override fun invoke(key: String): Set<String> =
synchronized(this) {
map.getOrPut(key) {
calculateValuesForKey(key)
}
}
}
Damiano Petrungaro
04/02/2022, 12:25 AMHello people!
I am new to Kotlin 🔥
I do have a Golang background, and I have to admit that I am enjoying it so far!
I’d love if some of you would give me some feedback about this project I am doing just as a server for practicing Kotlin 🙂
Let me know if you spot any bad practice in the source code, happy to receive some constructive feedback!
LeoColman
04/03/2022, 4:51 PMfun insertAll(uses: Iterable<Use>) {
uses.forEach { insert(it) }
uses.forEach(::insert)
}
What do you think about both approaches?ildar.i [Android]
04/12/2022, 12:08 PMVivek Modi
04/21/2022, 9:32 PMpackage com.example.kotlinmultiplatformsharedmodule
sealed class ApiResponse<out T : Any> {
data class Success<out T : Any>(
val data: T?
) : ApiResponse<T>()
data class Error(
val exception: Throwable? = null,
val responseCode: Int = -1,
val errorResponse: ErrorResponse? = null
) : ApiResponse<Nothing>()
fun handleResult(onSuccess: ((responseData: T?) -> Unit)?,onError: ((error: Error) -> Unit)?) {
when (this) {
is Success -> {
onSuccess?.invoke(this.data)
}
is Error -> {
onError?.invoke(this)
}
}
}
}
data class ErrorResponse(
val errorCode: Int,
val errorMessage: String
)
Ink
04/24/2022, 5:38 PMval productShopInfoItems = productListItemMapper.toShopInfoItems(it.snapshot)
state.productList.value?.forEach { product ->
productShopInfoItems.forEach { shop ->
if(product.productId == shop.productId){
product.shopInfoItemList += shop
}
}
}
product is
data class ProductItem(
val productId: String = "",
val productName: String = "",
var shopInfoItemList: List<ShopInfoResponseItem> = emptyList<ShopInfoResponseItem>()
)
Ellen Spertus
05/09/2022, 1:40 AMdialpad_0_holder.setOnClickListener { dialpadPressed('0', it) }
dialpad_9_holder.setOnClickListener { dialpadPressed('9', it) }
If the flag tremor
is true
, I would like to call setOnLongClickListener
instead of setOnClickListener
.
Is it possible to do something like this?
val f = if (tremor) RelativeLayout.onLongClickListener else RelativeLayout.onClickListener
dialpad_0_holder.f { dialpadPressed('0', it) }
dialpad_9_holder.f { dialpadPressed('9', it) }
Ellen Spertus
05/16/2022, 8:01 PMreturn binding.myField.getWidth() != 0 ? binding.myField.getWidth() : binding.otherField.getWidth()
2️⃣
return binding.myField.getWidth().let {
if (it != 0) it else binding.otherField.getWidth()
}
3️⃣ by @Luke
return if (binding.myField.getWidth() != 0) binding.myField.getWidth() else binding.otherField.getWidth()
Vivek Modi
05/17/2022, 9:31 AMval completeEvent = events?.lastOrNull { events -> events.status == "complete" }
val activeEvent = events?.find { events -> events.status == "active" }
val futureEvent = events?.firstOrNull { events -> events.status == "future" }
ApiResponse
"Events": [{
"title": "Test 1",
"status": "complete"
}, {
"title": "Test 2",
"status": "complete"
}, {
"title": "Test 3",
"status": "complete",
}, {
"title": "Test 4",
"status": "complete"
}, {
"title": "Test 5",
"status": "complete"
}, {
"title": "Test 6",
"status": "active"
}, {
"title": "Test 7",
"status": "future"
}, {
"title": "Test 8",
"status": "future"
}]
Jorge Domínguez
05/17/2022, 7:59 PMfun SomeEnum.getImageRes(
param: SomeOtherEnum
): Int {
return when (param) {
SomeOtherEnum.OtherEnumA -> {
when (this) {
SomeEnum.EnumA -> R.drawable.res1_a
SomeEnum.EnumB -> R.drawable.res1_b
}
}
SomeOtherEnum.OtherEnumB -> {
when (this) {
SomeEnum.EnumA -> R.drawable.res2_a
SomeEnum.EnumB -> R.drawable.res2_b
}
}
}
}
nikolaymetchev
06/01/2022, 10:32 AMuse
and with
should be added to the standard library:
inline fun <T : AutoCloseable?, R> T.useWith(block: T.() -> R): R = use(block)
inline fun <T : Closeable?, R> T.useWith(block: T.() -> R): R = use(block)
Mark
06/04/2022, 4:30 AMfun <T, R> Iterable<T>.singleOrNullBy(transform: (T) -> R): R? {
if (this is Collection && this.isEmpty()) return null
return asSequence()
.map(transform)
.zipWithNext()
.map { (a, b) -> if (a == b) a else null } // important we don't use mapNotNull here
.distinct()
.singleOrNull()
}
Mark
06/07/2022, 2:05 AMfun <T> Iterable<T>.splitByIndex(index: Int): Pair<List<T>, List<T>> {
if (index <= 0) {
return emptyList<T>() to this.toList()
}
val iterator = this.iterator()
val firstList = mutableListOf<T>()
val secondList = mutableListOf<T>()
var activeList = firstList
while (iterator.hasNext()) {
if (activeList.size == index) {
activeList = secondList
}
activeList.add(iterator.next())
}
return firstList to secondList
}
Is it okay to check the size
each time or better to maintain a local Int
count?Mark
06/07/2022, 2:05 AMfun <T> Iterable<T>.splitByIndex(index: Int): Pair<List<T>, List<T>> {
if (index <= 0) {
return emptyList<T>() to this.toList()
}
val iterator = this.iterator()
val firstList = mutableListOf<T>()
val secondList = mutableListOf<T>()
var activeList = firstList
while (iterator.hasNext()) {
if (activeList.size == index) {
activeList = secondList
}
activeList.add(iterator.next())
}
return firstList to secondList
}
Is it okay to check the size
each time or better to maintain a local Int
count?ephemient
06/07/2022, 2:09 AMList
it is definitely more efficient to use
fun <T> List<T>.splitAt(index: Int) = take(index) to drop(index)
since that uses .subList()
underneath which most List
implementations override (e.g. ArrayList
which returns a view with no extra allocation)List
index
is usually not very meaningfulsubList
but it doesn't seem to after allslice
does, thoughMark
06/07/2022, 2:14 AMIterable.take()
and I noticed something else:
if (this is Collection<T>) {
if (n >= size) return toList()
if (n == 1) return listOf(first())
}
Doesn’t that second line run into the problem you mentioned earlier?ephemient
06/07/2022, 2:15 AMCopyOnWriteArrayList
because it's one of the few data structures that actually has well-defined and useful behavior on concurrent modification. I would write generic code to make as few assumptions about the underlying data as possible, but it seems kotlin.collections is more optimized around non-mutating collections - which is probably reasonable for most Kotlin applicationsmutableListOf(...)
in one thread while reading it in another, there's no guarantees about consistency whatsoever, regardless of how safe the reader code is; it's only specific concurrent collections such as CopyOnWriteArrayList
which promise iterator()
stability)Mark
06/07/2022, 2:23 AMfun <T> Iterable<T>.splitAt(index: Int): Pair<List<T>, List<T>> {
if (index <= 0) {
return emptyList<T>() to this.toList()
}
if (this is List) { // optimization to avoid iterator
val safeList = this.toList()
if (index >= safeList.size) {
return safeList to emptyList()
}
return safeList.subList(0, index) to safeList.subList(index, safeList.size)
}
val iterator = this.iterator()
val firstList = mutableListOf<T>()
val secondList = mutableListOf<T>()
var activeList = firstList
while (iterator.hasNext()) {
if (activeList.size == index) {
activeList = secondList
}
activeList.add(iterator.next())
}
return firstList to secondList
}
BTW, I do have a use case for non-Lists. For example, a sorted set where you want to take the first few items and also do something with the remainder.
I suppose to be ultra safe, I should convert the List
using toList()
and only then apply subList
(UPDATED CODE)ephemient
06/07/2022, 2:33 AMbuildList {
repeat(index) {
if (!iterator.hasNext()) return@buildList
add(iterator.next())
}
} to buildList {
while (iterator.hasNext()) add(iterator.next())
}
but you could even do tricks like
Iterable { iterator }.take(index) to Iterable { iterator }.toList()
Mark
06/07/2022, 2:33 AMsafeList
anyway straight after the initial index check
fun <T> Iterable<T>.splitAt(index: Int): Pair<List<T>, List<T>> {
if (index <= 0) {
return emptyList<T>() to this.toList()
}
val safeList = this.toList()
if (index >= safeList.size) {
return safeList to emptyList()
}
return safeList.subList(0, index) to safeList.subList(index, safeList.size)
}
ephemient
06/07/2022, 2:35 AMMark
06/07/2022, 2:37 AMsubList
returns a view on the original list, so that may be why it’s better to first create a read-only list, but actually I prefer your idea:
fun <T> Iterable<T>.splitAt(index: Int): Pair<List<T>, List<T>> {
if (index <= 0) {
return emptyList<T>() to this.toList()
}
val iterator = iterator()
return Iterable { iterator }.take(index) to Iterable { iterator }.toList()
}