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

com.jtransc.ds.collectionutils.kt Maven / Gradle / Ivy

/*
 * Copyright 2016 Carlos Ballesteros Velasco
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.jtransc.ds

import java.util.*

inline fun  Iterable.cast() = this.filterIsInstance()

fun  queueOf(vararg items: T): java.util.Queue = LinkedList(items.toList())

fun  List>.uniqueMap(): HashMap? {
	val h = hashMapOf()
	val okay = this.all { x ->
		val y = h.put(x.first, x.second)
		(y == null) || (y == x.second)
	}
	return if (okay) h else null
}

val  List.head: T get() = this.first()
val  List.tail: List get() = this.drop(1)

fun  Map.flip(): Map = this.map { it.value to it.key }.toMap()

val  Pair, List>.zipped: List> get() {
	return this.first.zip(this.second)
}

class Queue() : Iterable {
	constructor(items: Iterable) : this() {
		queueAll(items)
	}

	private val data = LinkedList()

	val hasMore: Boolean get() = data.isNotEmpty()
	val length: Int get() = data.size

	fun queue(value: T): T {
		data.addFirst(value)
		return value
	}

	fun queueAll(items: Iterable): Queue {
		for (item in items) queue(item)
		return this
	}

	fun dequeue(): T {
		return data.removeLast()
	}

	override fun iterator(): Iterator = data.iterator()
}

class Stack(
	private var data: ArrayList = arrayListOf()
): Iterable {

	val hasMore: Boolean get() = data.isNotEmpty()

	val length: Int get() = data.size

	fun push(value: T): T {
		data.add(value)
		return value
	}

	fun pop(): T {
		return data.removeAt(data.size - 1)
	}

	fun clone(): Stack = Stack(ArrayList(data))


	override fun toString(): String = toList().toString()

	fun toList(): List = data.toList()

	override fun iterator(): Iterator = data.iterator()

	fun isEmpty() = !hasMore
	fun isNotEmpty() = hasMore
}

// @TODO: Make clearer!
fun  List.flatMapInChunks(chunkSize: Int, handler: (items: List) -> List): List {
	var out = this
	var n = 0
	while (n + chunkSize <= out.size) {
		//println("IN: $out")
		val extracted = out.slice(n until n + chunkSize)
		val toInsert = handler(extracted)
		out = out.slice(0 until n) + toInsert + out.slice(n + chunkSize until out.size)
		//println("OUT: $out")
		n++
	}
	return out
}

fun  List.flatMapInChunks2(chunkSize: Int, handler: (items: List) -> List): List {
	val out = arrayListOf()
	for (n in 0 until this.size / chunkSize) {
		//println("IN: $out")
		out.addAll(handler(this.slice(n * chunkSize until n * chunkSize + chunkSize)))
	}
	return out
}

fun  List?.createPairs(): List> {
	return this?.flatMapInChunks2(2) { listOf(Pair(it[0], it[1])) } ?: listOf()
}

fun  Map.toHashMap(): HashMap {
	val out = hashMapOf()
	for (pair in this) {
		out.put(pair.key, pair.value)
	}
	return out
}

fun  Iterable.stripNulls(): List {
	return this.filter { it != null }.map { it!! }
}

fun List.toTypedArray2(clazz: Class<*>): Any {
	val items = this
	val typedArray = java.lang.reflect.Array.newInstance(clazz, items.size)
	for (n in 0 until items.size) {
		java.lang.reflect.Array.set(typedArray, n, items[n])
	}
	return typedArray
}

fun List?.toTypedArray2(): Any? {
	if (this != null && this.isEmpty()) {
		//println("empty array!")
	}
	return this?.toTypedArray2(this.getOrNull(0)?.javaClass ?: Any::class.java)
}

data class DiffResult(val both: List, val justFirst: List, val justSecond: List)

fun  Iterable.diff(that: Iterable): DiffResult {
	val first = this
	val second = that
	val firstSet = first.toSet()
	val secondSet = second.toSet()

	return DiffResult(
		both = first.filter { it in secondSet },
		justFirst = first.filter { it !in secondSet },
		justSecond = second.filter { it !in firstSet }
	)
}

infix fun Int.clearFlags(that:Int) = (this and that.inv())
infix fun Int.hasFlag(that:Int) = (this and that) != 0
infix fun Int.hasAnyFlags(that:Int) = (this and that) != 0
infix fun Int.hasAllFlags(that:Int) = (this and that) == that

fun  List?>?.concatNotNull(): List {
	val out = arrayListOf()
	if (this != null) for (l in this) {
		if (l != null) {
			for (i in l) {
				if (i != null) out += i
			}
		}
	}
	return out
}

fun  Concat(vararg list: List?): List {
	var out = listOf()
	for (l in list) if (l != null) out += l
	return out
}

fun  List.split(separator: T): List> {
	val out = arrayListOf>()
	val part = arrayListOf()
	fun flush() {
		out += part.toList()
		part.clear()
	}
	for (item in this) {
		if (item == separator) {
			flush()
		} else {
			part += item
		}
	}
	flush()
	return out
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy