Invert Map<K, List<V>> to Map<V, K> - dictionary

map = mapOf((2: [3,4,5]), (7: [22,33,44]))
need to convert this to
mapOf(3:2, 4:2, 5:2, 22:7, 33:7, 44:7)
tried using associate with forEach, not sure of the syntax

There might be some nicer syntax, but this should work well enough.
fun main() {
val map = mapOf(
2 to listOf(3, 4, 5),
7 to listOf(22, 33, 44)
)
val transformedMap = map.flatMap { entry ->
entry.value.map { it to entry.key }
}.toMap()
println(transformedMap)
}
Prints
{3=2, 4=2, 5=2, 22=7, 33=7, 44=7}
Note that the toMap function states
The returned map preserves the entry iteration order of the original collection. If any of two pairs would have the same key the last one gets added to the map.
So if you have the same value in two different lists, only the last one will be included in the map.
fun main() {
val map = mapOf(
2 to listOf(3, 4, 5),
7 to listOf(22, 33, 44),
8 to listOf(3)
)
val transformedMap = map.flatMap { entry ->
entry.value.map { it to entry.key }
}.toMap()
println(transformedMap)
}
Prints {3=8, 4=2, 5=2, 22=7, 33=7, 44=7}

Zymus' answer is correct, and is also what I would probably write.
However, if this is something that will be called often, you might want to extract it to a separate function that is more efficient.
fun <K, V> Map<K, Iterable<V>>.invert(): Map<V, K> {
val newMap = mutableMapOf<V, K>()
for ((key, iterable) in this) {
for (value in iterable) {
newMap[value] = key
}
}
return newMap
}
Usage:
fun main() {
val map = mapOf((2 to listOf(3, 4, 5)), (7 to listOf(22, 33, 44)))
val inverted = map.invert()
println(inverted)
}
Output:
{3=2, 4=2, 5=2, 22=7, 33=7, 44=7}
This is functionally equivalent to
map.flatMap { (key, values) -> values.map { it to key } }.toMap()
including the behaviour where if there are duplicate values in the original input, only the last one will be preserved as a new key. However, the flatMap version creates many temporary Lists (the number of original keys + 1) and many temporary Pairs (the number of original values), whereas this iterative version creates no extra objects.

Related

collapse list of int to list of ranges in kotlin

I have a list of ints that needs to be compressed to list of int ranges without loosing any information (there must be a way to reverse this operation).
Currently I have:
val ints = listOf(8, 9, 45, 48, 49, 60, 61, 61, 62, 63, 3, 4, 5, 4, 5, 6)
val out = ints
.map { it..it }
.fold(mutableListOf(ints[0]..(ints[0] - 1)),
{ acc, next ->
val prev = acc.last()
if (prev.last + 1 == next.first) {
acc[acc.lastIndex] = prev.first..next.last
} else {
acc.add(next)
}
acc
}).toList()
That correctly produces:
[8..9, 45..45, 48..49, 60..61, 61..63, 3..5, 4..6]
There are two aspects I dislike in my solution though,
it does not work for empty list because of fold's initial value
it's quite verbose for kotlin. I have a feeling that this can be resolved in bit nicer way.
So, the question is how to fix 1 and/or 2?
Thanks in advance!
Since you actually mutate the acc and return the same list of ranges at all iterations of fold, you may not really need the fold, that is, forEach is enough.
Then, mapping each number to it..it seems to be redundant here.
Taking the two notes above into account leads to the following, a bit simplified, version of your solution:
val result = mutableListOf<IntRange>()
ints.forEach {
val lastRange = result.lastOrNull()
if (lastRange?.endInclusive == it - 1)
result[result.lastIndex] = lastRange.first..it
else
result += it..it
}
UPD: with the addition of buildList to the Kotlin standard library, you can rewrite the above as:
val result = buildList {
ints.forEach {
val last = lastOrNull()
if (last?.endInclusive == it -1) {
set(lastIndex, last.start..it)
} else {
add(it..it)
}
}
}
My solution doesn't look much different, but I was able to fix your empty list issue:
val out = ints.fold(mutableListOf<IntRange>()) { acc, next ->
acc.apply {
if(isNotEmpty() && last().endInclusive.inc() == next) {
this[lastIndex] = this[lastIndex].start .. next
} else {
add(next..next)
}
}
}
It's also a bit less mapping, and using apply takes away some of the verbosity and having to refer to acc at the end.

How best to find an element in nested lists?

Kotlin provides some usingful extension functions allow stream-like programming.
For example, if I look for an element in a list I can use find:
return list.find { n -> n>4 && n<6 }
But when I have a have nested lists this seems not practical for me. I have tu use forEach then -- luckyly I can return from an inner Lambda with Kotlin:
private fun findUsingForEach(data: List<List<Int>>, pred : (Int) -> Boolean) : Optional<Int> {
data.forEach { list ->
list.forEach { n ->
if( pred(n) ) return Optional.of(n)
}
}
return Optional.empty()
}
It seems fo me that forEach is not the right tool for that. Is there a more functional way to du this? filter comes to mind, but the nesting causes problems.
That follwing is the test I use for the function abouve:
#Test
open fun findTest() {
val data = listOf( listOf(1,2,3), listOf(3,4,5,6), listOf(), listOf(6,7,8) )
val e = findUsingForEach( data, { n -> n>4 && n < 6 } )
assertEquals(5, e.get())
}
You could flatten the list:
fun <T> Iterable<Iterable<T>>.flatten(): List<T> (source)
Returns a single list of all elements from all collections in the given collection.
val data = listOf(listOf(1, 2, 3), listOf(3, 4, 5, 6), listOf(), listOf(6, 7, 8))
data.flatten().find { n -> n > 4 && n < 6 }
This will return a single list with the elements of the sublists in order. Then you can use find as usual.
In your example,
{{1, 2, 3}, {3, 4, 5, 6}, {}, {6, 7, 8}}
becomes
{1, 2, 3, 3, 4, 5, 6, 6, 7, 8}
and the result of find on this list is 5.
However, this will create a new list. Take a look at the source of flatten:
/**
* Returns a single list of all elements from all collections in the given collection.
*/
public fun <T> Iterable<Iterable<T>>.flatten(): List<T> {
val result = ArrayList<T>()
for (element in this) {
result.addAll(element)
}
return result
}
If you want to save memory, create a Sequence from your list first:
data.asSequence()
and then perform your operations on this sequence:
data.asSequence().flatten().find { n -> n > 4 && n < 6 }
Side note: your predicate, n > 4 && n < 6, is simply equivalent to n == 5.
If you just want to reduce codes and you don't care much about efficiency, try this.
list.flatten().find { your pred here }
Or
list.flatMap { it }.find { your pred }
Or create a useful utility which doesn't create new lists (faster/lower memory taken):
inline fun <T> Iterable<Iterable<T>>.forEachEach(f: (T) -> Unit) =
forEach { it.forEach(f) }

How to reverse a Map in Kotlin?

I am trying to reverse a Map in Kotlin. So far, I have come up with:
mapOf("foo" to 42)
.toList()
.map { (k, v) -> v to k }
.toMap()
Is there any better way of doing this without using a middleman(middlelist)?
Since the Map consists of Entrys and it is not Iterable you can use Map#entries instead. It will be mapped to Map#entrySet to create a backed view of Set<Entry>, for example:
val reversed = map.entries.associateBy({ it.value }) { it.key }
OR use Iterable#associate, which will create additional Pairs.
val reversed = map.entries.associate{(k,v)-> v to k}
OR using Map#forEach:
val reversed = mutableMapOf<Int, String>().also {
// v-- use `forEach` here
map.forEach { (k, v) -> it.put(v, k) }
}.toMap()
// ^--- you can add `toMap()` to create an immutable Map.
Here is a simple extension function that reverse a map - without generating unneeded garbage (like pairs, intermediate data structures and unnecessary closures )
fun <K, V> Map<K, V>.reversed() = HashMap<V, K>().also { newMap ->
entries.forEach { newMap.put(it.value, it.key) }
}
note that apply is inlined, and entries.forEach is also inlined (which is not the same for Map::forEach)
In case your map is not a 1-1 mapping and you want the inversion to be a list of values:
mapOf(1 to "AAA", 2 to "BBB", 3 to "BBB").toList()
.groupBy { pair -> pair.second } // Pair<Int, String>
.mapValues { entry ->
entry.value.map { it.first } // Entry<String, List<Pair<Int, String>>
}
If you need to reverse a multimap like m: Map<K, List<V>> to a Map<V, List<K>> you can do
m
.flatMap { it.value.map { oneValue -> oneValue to it.key } }
.groupBy({ it.first }, { it.second })
.toMap()
In sequence,
mapOf('a' to listOf('b', 'c'), 'd' to listOf('b'))
gets flat mapped to a sequence like
listOf('b' to 'a', 'c' to 'a', 'b' to 'd') which gets grouped to
listOf('b' to listOf('a', 'd'), 'c' to listOf('a')) which then gets converted to a map.
This probably creates intermediate objects.
I'm still learning the ins and outs of Kotlin, but I had the same requirement and as of Kotlin 1.2 it appears that you can iterate over a Map and so map() it directly like this:
#Test
fun testThatReverseIsInverseOfMap() {
val intMap = mapOf(1 to "one", 2 to "two", 3 to "three")
val revMap = intMap.map{(k,v) -> v to k}.toMap()
assertTrue(intMap.keys.toTypedArray() contentEquals revMap.values.toTypedArray())
assertTrue(intMap.values.toTypedArray() contentEquals revMap.keys.toTypedArray())
}
This is my take on a 1:1 map
private fun <K, V> Map<K, V>.reverseOneToOneMap(): Map<V, K> {
val result = this.entries.associateBy({ it.value }) { it.key }
if (result.size != this.size) {
throw RuntimeException("Map must be 1:1")
}
return result
}

Golang: How to create unknown (dynamic) Map length

I can create a "static" map via
type m map[int]map[int]map[int]bool
but the length of "keys" will be dynamic:
|---unknown len--|
m[1][2][3][4][2][0] = true
or
|---unk len--|
m[1][2][3][4] = true
How I can create this map in Go? Or any way exists?
Added: Hierarchical is IMPORTANT
Thanks in advance!
The map type:
A map is an unordered group of elements of one type, called the element type, indexed by a set of unique keys of another type, called the key type.
A map type must have a specific value type and a specific key type. What you want does not qualify for this: you want a map where the value is sometimes another map (of the same type), and sometimes it's a bool.
Your options:
1. With a wrapper value type
The idea here is to not use just a simple (bool) value type, but a wrapper which holds both of your potential values: both a map and the simple value (bool):
type Value struct {
Children MapType
V bool
}
type MapType map[int]*Value
var m MapType
This is basically what user3591723 suggested, so I won't detail it further.
2. With a tree
This is a variant of #1, but this way we clearly communicate it's a tree.
The cleanest way to implement your hierarchical structure would be to use a tree, where a node could look like this:
type KeyType int
type ValueType string
type Node struct {
Children map[KeyType]*Node
Value ValueType
}
This has the advantage that you may choose the value type (which is bool in your case, but you can change it to whatever type - I used string for presentation).
For easily build / manage your tree, we can add some methods to our Node type:
func (n *Node) Add(key KeyType, v ValueType) {
if n.Children == nil {
n.Children = map[KeyType]*Node{}
}
n.Children[key] = &Node{Value: v}
}
func (n *Node) Get(keys ...KeyType) *Node {
for _, key := range keys {
n = n.Children[key]
}
return n
}
func (n *Node) Set(v ValueType, keys ...KeyType) {
n = n.Get(keys...)
n.Value = v
}
And using it: 1. build a tree, 2. query some values, 3. change a value:
root := &Node{Value: "root"}
root.Add(0, "first")
root.Get(0).Add(9, "second")
root.Get(0, 9).Add(3, "third")
root.Get(0).Add(4, "fourth")
fmt.Println(root)
fmt.Println(root.Get(0, 9, 3))
fmt.Println(root.Get(0, 4))
root.Set("fourthMod", 0, 4)
fmt.Println(root.Get(0, 4))
Output (try it on the Go Playground):
&{map[0:0x104382f0] root}
&{map[] third}
&{map[] fourth}
&{map[] fourthMod}
3. With a recursive type definition
It may be surprising but it is possible to define a map type in Go which has unlimited or dynamic "depth", using a recursive definition:
type X map[int]X
It is what it says: it's a map with int keys, and values of the same type as the map itself.
The big downside of this recursive type is that it can't store any "useful" data in the value type. It can only store the "fact" whether a value is present which is identical to a bool-like information (bool type: true or false), which may be enough in rare cases, but not in most.
Let's see an example building a "tree":
var x X
x = map[int]X{}
x[0] = map[int]X{}
x[0][9] = map[int]X{}
x[0][9][3] = map[int]X{}
x[0][4] = map[int]X{}
fmt.Println(x)
Output:
map[0:map[9:map[3:map[]] 4:map[]]]
If we want to test if there is a "value" based on a series of keys, we have 2 options: either use the special v, ok := m[i] indexing (which reports if a value for the specified key exists), or test if the value is not nil, e.g. m[i] != nil.
Let's see some examples testing the above built map:
var ok bool
_, ok = x[0][9][3]
fmt.Println("x[0][9][3] exists:", ok, "; alternative way:", x[0][9][3] != nil)
_, ok = x[0][9][4]
fmt.Println("x[0][9][4] exists:", ok, "; alternative way:", x[0][9][4] != nil)
_, ok = x[0][4]
fmt.Println("x[0][4] exists:", ok, "; alternative way:", x[0][4] != nil)
_, ok = x[0][4][9][9][9]
fmt.Println("x[0][4][9][9][9] exists:", ok, "; alternative way:", x[0][4][9][9][9] != nil)
Output:
x[0][9][3] exists: true ; alternative way: true
x[0][9][4] exists: false ; alternative way: false
x[0][4] exists: true ; alternative way: true
x[0][4][9][9][9] exists: false ; alternative way: false
Try these on the Go Playground.
Note: Even though x[0][4] is the last "leaf", indexing further like x[0][4][9][9][9] will not cause a panic as a nil map can be indexed and yields the zero value of the value type (which is nil in case the value type is a map type).
Ok I had some fun playing with this a bit. Here is a much better implementation than what I did before:
type mymap map[int]*myentry
type myentry struct {
m mymap
b bool
}
func (mm mymap) get(idx ...int) *myentry {
if len(idx) == 0 {
return nil
}
entry, ok := mm[idx[0]]
if !ok {
return nil
} else if len(idx) == 1 {
return entry
}
for i := 1; i < len(idx); i++ {
if entry == nil || entry.m == nil {
return nil
}
entry = entry.m[idx[i]]
}
return entry
}
func (mm mymap) setbool(v bool, idx ...int) {
if len(idx) == 0 {
return
}
if mm[idx[0]] == nil {
mm[idx[0]] = &myentry{m: make(mymap), b: false}
} else if mm[idx[0]].m == nil {
mm[idx[0]].m = make(mymap)
}
if len(idx) == 1 {
mm[idx[0]].b = v
return
}
entry := mm[idx[0]]
for i := 1; i < len(idx); i++ {
if entry.m == nil {
entry.m = make(mymap)
entry.m[idx[i]] = &myentry{m: make(mymap), b: false}
} else if entry.m[idx[i]] == nil {
entry.m[idx[i]] = &myentry{m: make(mymap), b: false}
}
entry = entry.m[idx[i]]
}
entry.b = v
}
func (m mymap) getbool(idx ...int) bool {
if val := m.get(idx...); val != nil {
return val.b
}
return false
}
func (m mymap) getmap(idx ...int) mymap {
if val := m.get(idx...); val != nil {
return val.m
}
return nil
}
Playground link
Something like that ought to get you started
If you don't need the hierarchical map structure and just want to use keys with variable length one approach could be to simply use strings as keys and one single map.
m := make(map[string]bool)
k := fmt.Sprintf("%v_%v_%v", 1, 2, 3)
m[k] = true
fmt.Println(m[k])
You cannot do this as this sort of type is not representable in Go's type system.
You will have to redesign.
E.g. a type arbitrarilyKeyedMapwith a method lookup(vals ...int) bool.
Probably you'll need methods for setting and deletion too.

Manipulating matrix data member in a Struct pointer method

I am working on creating a struct that represents a Matrix with methods to manipulate the data within the type. There are two methods that I use as an example to set a single row or column to a specific value. Here is a snippet of my code:
type Matrix struct {
Height, Width int
data [][]int
}
func NewMatrix(nrows, ncols int) (mat *Matrix) {
mat = new(Matrix)
mat.Height = nrows
mat.Width = ncols
mat.data = make([][]int, nrows)
for i := range mat.data {
mat.data[i] = make([]int, ncols)
for j := range mat.data[i]{
mat.data[i][j] = 0
}
}
return
}
func (mat *Matrix) SetCol(col, val int) {
for i := 0; i < mat.Height; i++ {
mat.data[i][col] = val
}
}
func (mat *Matrix) SetRow(row, val int) {
for i := 0; i < mat.Width; i++ {
mat.data[row][i] = val
}
}
When I use this Matrix type and manipulating the data attribute like so:
mat := NewMatrix(33,33)
mat.SetCol(2, 3)
mat.SetRow(2, 3)
I am finding that the data attribute of the Matrix instance is being set within the method SetCol but once it returns from this method the data appears to be the empty matrix that I initialized it to.
Why is the data attribute that I am manipulating in the method not persisting past the lifetime of the method call? How can I fix this?
Edit
I found out that the issue was that I was instantiating a new instance of a Matrix on each iteration in a loop which is why the matrix always appeared to be empty after I manipulated it with SetCol and SetRow. So the question is not really valid.

Resources