[JAVA] I want to use Clojure's convenient functions in Kotlin

Unique to functional languages? I investigated & created how to use the list operation function of Kotlin.

Building a list

range.clj


(def list1 (range 1 6))
(def list2 [6 6 7 8 7 7])

range.kt


val list1 = IntRange(1, 5)
val list2 = listOf(6, 6, 7, 8, 7, 7)

Kotlin is a Closed Range, isn't it?

List concatenation

concat.clj


(conj list2 10)
(concat list1 list2)

concat.kt


list2 + 10
list1 + list2

Infinite list

repeat.clj


(->> (repeat 123) (take 3))
(->> (iterate #(* 4 %) 3) (take 3))

repeat.kt


generateSequence { 123 }.take(3)
generateSequence(3) { it * 4 }.take(3)

List operation (basic)

filtering

filter, remove

filter.clj


(filter even? list1)
(remove even? list1)

filter.kt


list1.filter { it % 2 == 0 }
list1.filterNot { it % 2 == 0 }

some

some.clj


(some #(when (even? %) %) list1)

some.kt


list1.find { it % 2 == 0 }
list1.first { it % 2 == 0 }

If none match the condition, find returns null and first raises an exception.

mapping

map.clj


(map #(* % 2) list1)
(keep #(when (> % 3) (* % 2)) list1)
(map-indexed #(* %1 %2) list1)
(keep-indexed #(when (> % 3) (* % %2)) list1)
(mapcat #(list % (* % %)) list1)

map.kt


list1.map { it * 2 }
list1.mapNotNull { if (it > 3) it * 2 else null }
list1.mapIndexed { i, v -> i * v }
list1.mapIndexedNotNull { i, v -> if (i > 3) i * v else null }
list1.flatMap { listOf(it, it * it) }

Convolution

reduce.clj


(reduce #(* %1 %2) input)
(reduce #(* %1 %2) 10 input)
(reduce #(if (> % 20) (reduced %) (* % %2)) input)

reduce.kt


list1.reduce { acc, v -> acc * v }
list1.fold(10) { acc, v -> acc * v },
list1.reduce { acc, v -> if (acc > 20) return@reduce acc else acc * v }

If you want to stop reduce in the middle, you can use labeled return.

List operation (application)

The number of things that must be made will gradually increase.

Delete duplicates, delete consecutive duplicates

distinct.clj


(distinct list2)
(dedupe list2)

distinct.kt


fun <T> Iterable<T>.dedupe(): List<T> {
    if (count() == 0) return toList()
    return fold(listOf(first())) { acc, v -> if (v != acc.last()) acc + v else acc }
}

list2.distinct()
list2.dedupe()

shuffle

shuffle.clj


(shuffle list2)

shuffle.kt


import java.util.Collections

fun <T> Iterable<T>.shuffle(): List<T> = toMutableList().apply { Collections.shuffle(this) }

list2.shuffle()

apply is convenient, isn't it?

Construction of grouping map and appearance count map

groupby.clj


(group-by #(mod % 2) list2)
(frequencies list2)

groupby.kt


fun <T> Iterable<T>.frequencies(): Map<T, Int> = groupingBy { it }.eachCount()

list2.groupBy { it % 2 }
list2.frequencies()

Value scissors

interleave.clj


(interleave list1 list2)
(interpose 999 list1)

interleave.kt


fun <T> Iterable<T>.interleave(list: Iterable<T>): List<T> = zip(list).flatMap { it.toList() }

fun <T> Iterable<T>.interpose(sep: T): List<T> =
        zip(Collections.nCopies(count(), sep)).flatMap { it.toList() }.dropLast(1)

list1.interleave(list2)
list1.interpose(999)

Cumulative calculation

reductions.clj


(reductions * list1)
(reductions * 10 list1)

reductions.kt


fun <T> Iterable<T>.reductions(function: (T, T) -> T): List<T> {
    if (count() <= 1) return toList()
    return drop(1).reductions(first(), function)
}

fun <T, R> Iterable<T>.reductions(init: R, function: (R, T) -> R): List<R> {
    if (count() == 0) return listOf(init)
    return fold(listOf(init)) { acc, v -> acc + function(acc.last(), v) }
}

list1.reductions { i, j -> i * j }
list1.reductions(10, Int::times)

Split the list every n

partition.clj


(partition 3 list1)
(partition-all 3 list1)
(partition 4 2 list1)
(partition-all 4 2 list1)
(partition 4 2 [:a :b] list1)

partition.kt



fun <T> Iterable<T>.partition(n: Int, step: Int = n, pad: List<T> = listOf<T>()): List<List<T>> {
    var tmp = toList()
    return mutableListOf<List<T>>().apply {
        while (tmp.count() >= n) {
            add(tmp.take(n))
            tmp = tmp.drop(step)
        }
        if (!pad.isEmpty() && !tmp.isEmpty())
            add((tmp + pad).take(n))
    }
}

fun <T> Iterable<T>.partitionAll(n: Int, step: Int = n): List<List<T>> {
    var tmp = toList()
    return mutableListOf<List<T>>().apply {
        while (!tmp.isEmpty()) {
            add(tmp.take(n))
            tmp = tmp.drop(step)
        }
    }
}

list1.partition(3)
list1.partitionAll(3)
list1.partition(4,2)
list1.partitionAll(4,2)
list1.partition(4,2,listOf("a","b"))

The partition function originally in Kotlin returns Pair <List <T>, List <T >>, so the usage is different.

Split the list according to conditions

partitionby.clj


(partition-by identity list2)
(partition-by #(> % 7) list2)

partitionby.kt


fun <T, R> Iterable<T>.partitionBy(function: (T) -> R): List<List<T>> {
    if (count() == 0) return listOf()

    return drop(1).fold(listOf(listOf(first()))) { acc, v ->
        if (function(acc.last().last()) != function(v))
            acc + listOf(listOf(v))
        else
            acc.dropLast(1) + listOf(acc.last() + v)
    }
}

list2.partitionBy { it }
list2.partitionBy { it > 7 }

Recommended Posts

I want to use Clojure's convenient functions in Kotlin
I want to use @Autowired in Servlet
I want to use arrow notation in Ruby
I want to be eventually even in kotlin
I want to use Combine in UIKit as well.
I want to use fish shell in Laradock too! !!
I want to use ES2015 in Java too! → (´ ・ ω ・ `)
I want to use a little icon in Rails
I want to use FormObject well
I want to implement various functions with kotlin and java!
I want to use DBViewer with Eclipse 2018-12! !!
[Java Spring MVC] I want to use DI in my own class
I want to send an email in Java.
I want to use java8 forEach with index
I want to pass APP_HOME to logback in Gradle
rsync4j --I want to touch rsync in Java.
[Xcode] I want to manage images in folders
I want to get the value in Ruby
I want to do something like "cls" in Java
I want to use NetBeans on Mac → I can use it!
I want to embed any TraceId in the log
If you want to use Mockito with Kotlin, use mockito-kotlin
I want to define a function in Rails Console
[Android Studio] I want to use Maven library on Android
I want to transition screens with kotlin and java!
I want to stop snake case in table definition
I want to click a GoogleMap pin in RSpec
I want to use PowerMock in a class that combines parameterized tests and ordinary tests
I want to convert characters ...
[Beginner] I want to modify the migration file-How to use rollback-
I want to find a relative path in a situation using Path
I want to set the conditions to be displayed in collection_check_boxes
I want to use screen sharing on the login screen on Ubuntu 18
I want to perform high-speed prime factorization in Ruby (ABC177E)
I want to make a list with kotlin and java!
I want to make a function with kotlin and java!
I want to use the Java 8 DateTime API slowly (now)
I want to use the sanitize method other than View.
How to use ArgumentMatchers such as Mockito's any () in Kotlin
Even in Java, I want to output true with a == 1 && a == 2 && a == 3
I want to create a Parquet file even in Ruby
I tried to implement a buggy web application in Kotlin
I want to transition to the same screen in the saved state
I want to use FireBase to display a timeline like Twitter
Delegate is convenient to use when you want to reuse parts
I want to simplify the conditional if-else statement in Java
How to use Lombok in Spring
ProxyFactory is convenient when you want to test AOP in Spring!
I want to use swipeback on a screen that uses XLPagerTabStrip
I want to return to the previous screen with kotlin and java!
[Ruby] I want to put an array in a variable. I want to convert to an array
I tried setting Java beginners to use shortcut keys in eclipse
I want to convert InputStream to String
I want to get some properties as JSON strings in Jackson!
I want to docker-compose up Next.js!
How to use InjectorHolder in OpenAM
I want to display the images under assets/images in the production environment
I want to add devise in Rails, but I can't bundle install
How to use classes in Java?
I want to remove the top margin in Grouped UITableView (swift)
[Java] I want to perform distinct with the key in the object