All Downloads are FREE. Search and download functionalities are using the official Maven repository.

graphql.nadel.enginekt.util.CollectionUtil.kt Maven / Gradle / Ivy

Go to download

Nadel is a Java library that combines multiple GrahpQL services together into one API.

The newest version!
package graphql.nadel.enginekt.util

import java.util.Collections
import kotlin.collections.component1
import kotlin.collections.component2
import kotlin.collections.set

/**
 * Like [singleOrNull] but the single item must be of type [T].
 */
inline fun  Collection<*>.singleOfTypeOrNull(predicate: (T) -> Boolean = { true }): T? {
    return singleOrNull { it is T && predicate(it) } as T?
}

/**
 * Like [singleOrNull] but the single item must be of type [T].
 */
inline fun  Collection<*>.singleOfType(predicate: (T) -> Boolean = { true }): T {
    return singleOfTypeOrNull(predicate)!!
}

inline fun  Iterable.strictAssociateBy(crossinline keyExtractor: (E) -> K): Map {
    return mapFrom(
        map {
            keyExtractor(it) to it
        }
    )
}

inline fun  Sequence.strictAssociateBy(crossinline keyExtractor: (E) -> K): Map {
    val map = mutableMapOf()
    var count = 0
    forEach {
        map[keyExtractor(it)] = it
        count++
    }
    require(map.size == count)
    return Collections.unmodifiableMap(map)
}

/**
 * Like [mapOf] but takes in a [Collection] instead of vararg. Useful if your input
 * into the [Map] is [List.map]ped from another [Collection].
 */
@JvmName("mapFromPairs")
fun  mapFrom(entries: Collection>): Map {
    val map = HashMap(entries.size)
    map.putAll(entries)
    require(map.size == entries.size) {
        @Suppress("SimpleRedundantLet") // For debugging purposes if you want to visit the values
        "Duplicate keys: " + entries.groupBy { it.first }.filterValues { it.size > 1 }.let {
            it.keys
        }
    }
    return map
}

/**
 * Like [mapOf] but takes in a [Collection] instead of vararg. Useful if your input
 * into the [Map] is [List.map]ped from another [Collection].
 */
@JvmName("mapFromPairs")
fun  mapFrom(entries: Sequence>): Map {
    val map = HashMap()
    var count = 0
    entries.forEach {
        map[it.first] = it.second
        count++
    }
    require(map.size == count) {
        @Suppress("SimpleRedundantLet") // For debugging purposes if you want to visit the values
        "Duplicate keys: " + entries.groupBy { it.first }.filterValues { it.size > 1 }.let {
            it.keys
        }
    }
    return map
}

fun  Sequence>.toMapStrictly(): Map {
    return mapFrom(entries = this)
}

fun  Collection>.toMapStrictly(): Map {
    return mapFrom(entries = this)
}

/**
 * Like [mapOf] but takes in a [Collection] instead of vararg. Useful if your input
 * into the [Map] is [List.map]ped from another [Collection].
 */
@JvmName("mapFromEntries")
fun  mapFrom(entries: Collection>): Map {
    val map = HashMap(entries.size)
    entries.forEach(map::put)
    require(map.size == entries.size)
    return map
}

/**
 * Utility function to set the [Map.Entry.key] to [Map.Entry.value] in the given [MutableMap].
 */
fun  MutableMap.put(entry: Map.Entry) {
    put(entry.key, entry.value)
}

/**
 * Utility function to set the [Map.Entry.key] to [Map.Entry.value] in the given [MutableMap].
 */
fun  MutableMap.put(entry: Pair) {
    put(entry.first, entry.second)
}

/**
 * Inverts the [Map] such that the values are now the keys and the keys are now the values.
 */
fun  Map.invert(): Map {
    val map = HashMap(this.size)
    forEach { (key, value) ->
        map[value] = key
    }
    require(map.size == this.size)
    return map
}

/**
 * Try to replace the function body with just:
 *
 * ```kotlin
 *putAll(map)
 * ```
 *
 * If it works then yay we don't need this function anymore, but right now I'm getting:
 *
 * Type mismatch
 *
 * Required: Map
 *
 * Found:    Map<*, *>
 */
fun AnyMutableMap.hackPutAll(map: AnyMap) {
    @Suppress("UNCHECKED_CAST")
    (this as MutableMap).putAll(map)
}

/**
 * This function permits an empty collection or a [single] object in the collection.
 *
 * @return null if empty or [single] object
 * @see single
 */
fun  Iterable.emptyOrSingle(): T? {
    return when (this) {
        is List -> when (isEmpty()) {
            true -> null
            else -> single()
        }
        else -> iterator().emptyOrSingle()
    }
}

/**
 * See `Iterable`.[emptyOrSingle]
 */
fun  Iterator.emptyOrSingle(): T? {
    return when (hasNext()) {
        true -> next().also {
            if (hasNext()) {
                // Copied from List.single
                throw IllegalArgumentException("List has more than one element.")
            }
        }
        else -> null
    }
}

/**
 * See `Iterable`.[emptyOrSingle]
 */
fun  Sequence.emptyOrSingle(): T? {
    return iterator().emptyOrSingle()
}

inline fun  Map.filterValuesOfType(): Map {
    @Suppress("UNCHECKED_CAST")
    return filterValues {
        it is T
    } as Map
}

fun Sequence.flatten(recursively: Boolean): Sequence {
    return flatMap { element ->
        when (element) {
            is AnyMap -> sequenceOf(element)
            is AnyIterable -> element.asSequence().let {
                if (recursively) {
                    it.flatten(recursively = true)
                } else {
                    it
                }
            }
            else -> sequenceOf(element)
        }
    }
}

/**
 * See [List.subList], but if input is out of bounds then null is returned instead.
 */
fun  List.subListOrNull(fromIndex: Int, toIndex: Int): List? {
    if (fromIndex < 0 || /*toIndex is exclusive, hence minus 1*/ toIndex - 1 > lastIndex) {
        return null
    }

    return subList(fromIndex = fromIndex, toIndex = toIndex)
}

fun  Iterable.foldWhileNotNull(initial: R, operation: (acc: R, T) -> R): R? {
    var accumulator = initial
    for (element in this) {
        accumulator = operation(accumulator, element) ?: return null
    }
    return accumulator
}

fun  listOfNulls(size: Int): List {
    return ArrayList(size).also {
        for (i in 1..size) {
            it.add(null)
        }
    }
}

fun  sequenceOfNulls(size: Int): Sequence {
    return sequence {
        for (i in 1..size) {
            yield(null)
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy