I am trying to create a map in scala
var map1:Map[String,List[String]] from a list of tuples
input : List(("a1",1),("a1",2),("b1",3),("c1",2),("c1",3),("c1",4))
def fn(List[String]): which takes input as List of tuples and globally declared Map is updated and finally result Map with Value Lists.
output : Map(a1->[1,2], b1->[3], c1->[2,3,4])
How to create a function that can achieve the same by first searching key and appending in the value list.
Here is a code for your logic, which accepts list of tuples as input and returns value Map with key and value list.
import scala.collection.immutable._
//function which accepts List of Tuples and returns Map
def convertListToMap(inputParam:List[(String, Int)]) : Map[String,List[Int]]={
inputParam.groupBy(_._1).mapValues(_.map(_._2))
}
//List of Tuples as inputs
val input=List(("a1",1),("a1",2),("b1",3),("c1",2),("c1",3),("c1",4))
//List((a1,1), (a1,2), (b1,3), (c1,2), (c1,3), (c1,4))
//invoking convertListToMap
convertListToMap(input)
//Output: Map(a1 -> List(1, 2), c1 -> List(2, 3, 4), b1 -> List(3))
// remaining logic to proceed further
Related
I'm using Scala and I have a tuple (String, List[Int]) like this:
("tom", [1,2,3])
I need to apply a function to the second element of this tuple and to return a list of tuples. Say, I want to multiply the elements in the list by 2, so the output should be:
[("tom", 2), ("tom", 4), ("tom", 6)]
How to do this?
As #Luis says, the idea is that you use map.
First you get your list out of the input tuple. Here's one way to do it.
val name, values = ("tom", List(1,2,3))
Next you iterate over that list. For each element, you convert it into a new tuple with a constant name and the value multiplied by 2.
val result = values.map(x => (name, 2*x))
I'm looking to iterate over a list of tuples and extract the second value from each tuple. I'd then like to add these values to a new list.
Each tuple in my list consists of a string and an int:
y = List((this, 1), (is, 2), (a, 3), (test, 4)
I can successfully iterate over each tuple and extract the int using:
for (x <- y) {
val intValue = x._2
println(intValue)
}
This gives me
1
2
3
4
I'm then looking to add those values to a list. Any help would be appreciated.
There is no need to use for here, a simple map will do:
y.map(_._2)
The map function creates a new List from the old one by calling a function on each element of the List.
The function _._2 is a shorthand for x => x._2. This just returns the second value in the tuple, which is the Int you want to extract.
You can use map function as #Tim explained or just use yield like in:
val list = for ((_,b) <- y) yield b
I have Erlang function that returns the last element of a list
lastElement([H|[]]) ->H;
lastElement([H|T]) ->lastElement(T).
and a function that returns a list without last element
withoutLastElement([H|[]], Result) ->Result;
withoutLastElement([H|T]) ->withoutLastElement(T, [H|Result]).
so i browse the same list for two times, and for more efficiency i want to do only a function that returns the last element of a list and returns this list without this element in one browse, this is easy in another language but i can't do that in Erlang so any help and thank you all.
You'd usually return the two values in a tuple:
list_and_last(List) ->
list_and_last(List, []).
list_and_last([H], Result) ->
{H, Result};
list_and_last([H|T], Result) ->
list_and_last(T, [H|Result]).
Calling list_and_last with [1,2,3] returns {3,[2,1]}.
In Erlang you can return a tuple, so you simply define a tuple with the last element and the list:
... -> {last_element, list}
You retrieve the value with pattern matching:
{Element, List} = last_element_and_new_list(The_List)
The last element and list will be bound to the respective variables. Note that you can return more than two values in a tuple.
You can simply reverse the list:
List = [1, 2, 3, 4, 5, 6],
[Last | Rest] = lists:reverse(List)
I have a list:
alist =
[('A','1','2','DEF'),('B','100,'11','XYZ'),('C','6','9','ABC')]
and I want to sort the list on 2nd and 3rd element, but before I do so I want to convert the type of these elements from string to integer. How can I do so in most pythonic way?
I know I can read the list, convert elements to integer, add all elements to a new list and finally sort:
newList = []
for i in alist:
a,b,c,d, = i
newList.append((a,int(b),int(c),d))
newList.sort(key=itemgetter(1,2))
but what if each tuple in my list has 100 elements (above list had just 4) and I just want to convert a few them (like in above list - b and c) to integer type?
Bade
There's no need to convert them if you only want to sort on them:
alist.sort(key=lambda x: (int(x[1]), int(x[2])))
...
newList = sorted(alist, key=lambda x: (int(x[1]), int(x[2])))
If I inderstand the question, you really want to sort tuples by key, which needs to be converted to integer.
I would do
sorted_list = sorted(alist, key=lambda tup: int(tup[1]))
Let's say that I have a Map of strings -> List of Integers. I would like to create a function which takes in as a parameter a List of strings and returns all the integers correlating to all the string in that list. I.e. if the Map X contains the following mappings:
database = [("Bob",[1,2,3]),("John",[1,5,6]),("Trevor",[4,5,7])]
If this function takes in ["Bob","John"] as the list of names, it should return,
[1,2,3,5,6]
Since Bob correlates to 1,2,3 and John correlates to 1,5,6 (same entries for both names aren't duplicated). I also would like to not introduce a mutable variable if I don't have to, thus leading me to believe a for comprehension that yields this list of number values would be the best way to achieve this, but I'm not sure how.
If you want to use a for-comprehension you can so this:
val result = for {
key <- keys
nums <- map.get(key).toSeq
num <- nums
} yield num
result.distinct
Explanation:
for each key in the list try to get an entry and convert it to a Seq (necessary because flatMap expects a Seq in this case) and add every number in the list to the result. If the key is not present in the map the collection will be empty and therefore not yield any results. At the end call distinct to remove the duplicates.
val myMap = Map("Bob" -> List(1,2,3), "John" -> List(1,5,6), "Trevor" -> List(4,5,7))
val names = List("Bob", "John")
You can add default value to Map using method withDefaultValue:
val mapWithDefaul = myMap withDefaultValue Nil
Then you could use Map as function in flatMap:
names.flatMap(mapWithDefaul).distinct
// List(1, 2, 3, 5, 6)
Let
val db = Map("Bob" -> List(1,2,3), "John" -> List(1,5,6), "Trevor" -> List(4,5,7))
val names = List("Bob", "John")
Then a similar approach to #senia's using flatMap,
implicit class mapCorr[A,B](val db: Map[A,List[B]]) extends AnyVal {
def corr(keys: List[A]): List[B] = {
keys.flatMap{ k => db get k }.flatten.distinct
}
}
and
scala> db.corr(keys)
res0: List[Int] = List(1, 2, 3, 5, 6)
Here we allow for key lists of type A and maps from type A to type List[B] .
val myset = Set("Bob","John")
val database = Map(("Bob"->List(1,2,3)),("John"->List(1,5,6)),("Trevor"->List(4,5,7)))
val ids = database.filter(m => myset.contains(m._1)).map(_._2).flatten.toList.distinct
outputs:
ids: List[Int] = List(1, 2, 3, 5, 6)
Something like:
val result = database.filter(elem => list.contains(elem._1)).foldLeft(List())((res,elem) => res ++ elem._2)
where list is the input list of names.