I have a map as follows
val parentMap= mutableMapOf<String,String>()
parentMap["key1"]="value1"
parentMap["key2"]="value2"
parentMap["key3"]="value3"
And I have a list of keys val keyList= listOf("key1","key3")
I want to remove the key from map which doesn't exist in my keylist
The current solution I am using is
val filteredMap= mutableMapOf<String,String>()
keyList.forEach {
if(parentMap.containsKey(it))
filteredMap[it]=parentMap[it]!!
}
println(filteredMap)
Is there any more better way to do this?
This can be achieved even a little shorter:
val map = mapOf(
"key1" to "value1",
"key2" to "value2",
"key3" to "value3"
)
val list = listOf("key1")
val filteredMap = map.filterKeys(list::contains)
the result is: {key1=value1}
You can do it much easier like this:
val filteredMap = parentMap.filter { keyList.contains(it.key) }
Related
Say, I have the following url.
I store the keyValues in a dictionary
let strURL = "https://www.x.com/?d=1&a=2&b=3&c=4&nbr=1234567890"
let items = URLComponents(string:strURL)?.queryItems
var KeyValues:[String:String] = [:]
items?forEach {
item in KeyValues[item.name] = item.value
}
Problem : how to sort it and output a string from the KeyValues such that
string = "a=1&b=2&c=3&d=4&nbr=1234567890"
Thanks
This is how I did it:
let sorted = KeyValues.map { $0 }.sorted { $0.key < $1.key }
let result = sorted.dropFirst().reduce("\(sorted.first!.key)=\(sorted.first!.value)") { (result, kvp) -> String in
result + "&\(kvp.key)=\(kvp.value)"
}
We first turn the dictionary into a [(String, String)] then we sort it according to the key.
Then, we reduce the sorted array to join the keys and values together.
I have a list of two-item lists:
def list = [[key1, value1], [key1, value1], [key2, value1], [key2, value2], ...]
I am trying to write Groovy code which will take "list" and return another list, which displays not only the frequency of each duplicate, two-item list, but also if there are items which are unique:
def newList = [[key1, value1:2], [key2, [value1:1, value2:1]], ...];
The reasoning behind this format is because I'd write more code to throw an error if a specific "key" had more than one "value". If there is an easier way to do this, any help/suggestions would be appreciated.
It normally helps if you show what you've tried when asking a question here...
In this case though, you just need:
def result = list.groupBy { it[0] }
.collect { k, v -> [k, v.countBy { it[1] }] }
And result will equal:
[['key1', ['value1':2]], ['key2', ['value1':1, 'value2':1]]]
You could also do something like this:
def result = list.groupBy { it[0] }
.collectEntries { k, v -> [k, v*.getAt(1).unique().size() ] }
To give you:
['key1':1, 'key2':2]
How I can merge in short way two maps by their keys but they could have different keys.
For example I have
val query1 = Map(("email", "aa#ya.ru"), ("phone", "ph0997832"))
val query2 = Map(("email", "bb#ya.ru"), ("fax", "fax0997832"))
And I want something like that:
List("email", "phone", "fax")
List(List("aa#ya.ru", "ph0997832", ""), List("bb#ya.ru", "", "fax0997832"))
Using :
scala> val queries = List(query1, query2)
queries: List[Map[String,String]] = List(
Map(email -> aa#ya.ru, phone -> ph0997832),
Map(email -> bb#ya.ru, fax -> fax0997832)
)
Getting the keys is easy enough; call .keys on every Map, flatten the result and remove the duplicates :
scala> val keys = queries.flatMap(_.keys).distinct
keys: List[String] = List(email, phone, fax)
Getting the second list; fetch the value of all keys for queries, using .getOrElse(k, "") to get an empty string instead of a None :
scala> queries.map(q => keys.map(k => q.getOrElse(k, "")))
res0: List[List[String]] = List(List(aa#ya.ru, ph0997832, ""),
List(bb#ya.ru, "", fax0997832))
How can I convert a map to a list without the map keys being involved in the list in scala?
val mp = collection.mutable.Map[Long, String]()
mp(0) = "val0"
mp(1) = "val1"
mp(2) = "val2"
mp.toList //I want: List("val0", "val1", "val2")
You are probably looking for
mp.values.toList
I have a IndexedSeq[Map[String, String]] and I would like to extract value where key is "text" and I would like to put it in a val text:IndexedSeq[String]. I have written the following piece but it doesn't work:
val text:IndexedSeq[String] = _
for(j <- 0 to indSeq.length-1){
text(j) = indSeq(j).get("text")
}
You are probably seeing a compiler error because indSeq(j).get("text") returns an Option[String], not a String.
If you just want to get all the values for the key "text" in a sequence, use:
val text = indSeq flatMap (_ get "text")
If it's important that the indices of both sequences line up, then you will want to substitute a default value in case the key "text" is not present:
val text = indSeq map (_.getOrElse("text", "default"))
I think the best approach is with a for-comprehension with a guard to get rid of the maps that don't have the "text" element:
val result = for {
i <- 0 until indexSeq.length
map = indexSeq(i)
if map isDefinedAt ("text")
} yield { (i, map("text")) }
val seq = result.toIndexedSeq
That way you keep the original indexes with the map. It also avoids holding any var value, which is always a perk
Since you were trying to use a for-comprehension originally, you might also be interested in doing it this way:
val text = (for { m <- indSeq } yield m get "text") flatten
EDIT
or if you want a default value you could do:
val text = for { m <- indSeq } yield m getOrElse("text", "default")