How do I perform an operation that checks the IDs and removes the different elements of the first list and adds the different elements of the second list?
The letters are a Entity Id. The numbers are a object reference in memory.
List 1: A:1, B:2, C:3, D:4, E:5
List 2: B:6, C:7, E:8, F:9
RemovedElements: A:1, D:4
InvalidElements: B:6, C:7, E:8
ResultList: B:2, C:3, E:5, F:9
Does anyone know if there is any function that performs this operation?
scala> val l1 = Seq(('A', 1), ('B', 2), ('C', 3), ('D', 4), ('E', 5))
l1: Seq[(Char, Int)] = List((A,1), (B,2), (C,3), (D,4), (E,5))
scala> val l2 = Seq(('B', 6), ('C', 7), ('E', 8), ('F', 9))
l2: Seq[(Char, Int)] = List((B,6), (C,7), (E,8), (F,9))
scala> l2 map { e =>
| l1.find(_._1 == e._1).getOrElse(e)
| }
res51: Seq[(Char, Int)] = List((B,2), (C,3), (E,5), (F,9))
Related
I want to check if a list is a subset of another, based on the first element in its tuple.
subset(List(('a', 1), ('b', 2), ('c', 3)), List(('a', 4), ('b', 5)) // True
subset(List(('a', 1), ('b', 2), ('c', 3)), List(('a', 4), ('b', 5), ('f', 6)) // False
The size of the lists does not have to be the same. I've tried something like this, but with no luck
x.forall((char: Char, num: Int) => {y.contains((_,num))})
You can map in the input lists to retain only the first element, then use some set functionality to check equality:
def subset(a: List[(Char, Int)], b: List[(Char, Int)]): Boolean = {
val a_ = a.map(_._1).toSet
val b_ = b.map(_._1).toSet
b_.subsetOf(a_)
}
Update: Simplified based on suggestion from Luis
I'm working on a problem to take two lists, for example (1,2,3) and (a,b) and return a list ((1,a)(1,b)(2,a)(2,b)(3,a)(3,b)) using only map and flatten.
This problem requires me to define a function as follows:
def product[A](xs: List[A], ys: List[A])= {
And within this function get the result. I'm rather new to Scala and I am used to languages like python and java.
I've gotten this far:
def product[A](xs: List[A], ys: List[A])= {
for(y <- ys){
println(xs.map(x=> (x,y)))
}
}
This will return something like this:
List((1,a), (2,a), (3,a))
List((1,b), (2,b), (3,b))
I'm not sure how can combine these lists now. In python I would do something like create a new list variable, append both of these lists to that list, and then flatten it so I would have one list. However, I'm rather confused by scala as it seems as if I am not allowed to define a new variable within a function. How can I combine these lists and flatten them at this point?
Product List using only map and flatten
val nums = List(1, 2, 3)
val chars = List('a', 'b')
nums.map { a => chars.map { b => (a, b) } }.flatten
Scala REPL
scala> nums.map(a => chars.map(b => (a, b)))
res5: List[List[(Int, Char)]] = List(List((1, 'a'), (1, 'b')), List((2, 'a'), (2, 'b')), List((3, 'a'), (3, 'b')))
scala> nums.map(a => chars.map(b => (a, b))).flatten
res6: List[(Int, Char)] = List((1, 'a'), (1, 'b'), (2, 'a'), (2, 'b'), (3, 'a'), (3, 'b'))
Product List can be built using flatMap and map combination
nums.flatMap { a => chars.map { b => (a, b) }}
Product List can also be built using for comprehension
for {a <- nums; b <- chars} yield (a, b)
Scala REPL
scala> val nums = List(1, 2, 3)
val nums: List[Int] = List(1, 2, 3)
scala> val chars = List('a', 'b')
chars: List[Char] = List('a', 'b')
scala> nums.flatMap { a => chars.map { b => (a, b) }}
res2: List[(Int, Char)] = List((1, 'a'), (1, 'b'), (2, 'a'), (2, 'b'), (3, 'a'), (3, 'b'))
scala> for {a <- nums; b <- chars} yield (a, b)
res3: List[(Int, Char)] = List((1, 'a'), (1, 'b'), (2, 'a'), (2, 'b'), (3, 'a'), (3, 'b'))
You can solve it using for comprehension. It's actually a syntactic sugar for map and flatMap:
def product[A](xs: List[A], ys: List[A])= {
for {
x <- xs
y <- ys
} yield {
x -> y
}
}
For-comprehensions is the Scala idiomatic way to achieve this. It's more readable and maintainable, and the underlying operations are still map and flatMap. In fact, even for types that are not collections, but still have map and flatMap, it's common to use for comprehensions (Futures, Options, Trys, etc.)
Edit
If you want to continue with your solution and save the lists and combine them, you'll have to drop the println and add a yield, and then flatten the main list that was created:
def product[A](xs: List[A], ys: List[A]) = {
for (y <- ys) yield {
xs.map(x => (x, y))
}
}
val res = product(List(1, 2, 3), List("a", "b"))
println(res.flatten)
val ls1 = List(1,2,3)
val ls2 = List('a','b')
def product[A](xs: List[A], ys: List[A])= xs.map(x => ys.map((x,_))).flatten
product(ls1,ls2)
I have a list that looks like this List(List(0, 2), List(0, 3), List(2, 3), List(3, 2), List(3, 0), List(2, 0))), note this list will only contain pairs and will not contain duplicate pairs. I want to sort the list in descending order by the second item in each sub list in this larger list. If there are duplicate values I don't really which comes first.
For this instance the answer could look like List(List(0,3), List(2,3), List(0,2), List(3,2), List(3,0), List(2,0))
My idea was looping through the larger list and get a list containing each second item in each pair and sort those but I am having trouble keeping track of which second item in each pair belong to which pair afterwards. Perhaps there is a more clever way?
A simple solution would be:
list.sortBy(-_.last)
You can simply do:
list.sortBy(-_(1))
If the lists are always length 2, I would use tuples instead of lists. Then it is just a matter of using sortBy
scala> val l1 = List(List(0, 2), List(0, 3), List(2, 3), List(3, 2), List(3, 0), List(2, 0))
l1: List[List[Int]] = List(List(0, 2), List(0, 3), List(2, 3), List(3, 2), List(3, 0), List(2, 0))
scala> val l2 = l1.map(x => (x(0), x(1)))
l2: List[(Int, Int)] = List((0,2), (0,3), (2,3), (3,2), (3,0), (2,0))
scala> l2.sortBy(-_._2)
res1: List[(Int, Int)] = List((0,3), (2,3), (0,2), (3,2), (3,0), (2,0))
list.sortBy( sublist => -1 * sublist.tail.head )
please can someone help me with the codes for this nested list of numbers to look like the nested list of tuples below ie from pot to val.
pot = [[1,2,3,4],[5,6,7,8]]
val = [[(1,2),(2,3),(3,4)],[(5,6),(6,7),(7,8)]]
I used a grouper function but it didn't quite give me the desired result. Is there another way ? Thanks
for line in pot:
temp = []
for i in range(len(line)-1):
temp.append( (line[i],line[i+1]) )
val.append(temp)
May contain typos.
There's probably a better way to do it but I noticed there was no answer to your question and worked something out that does the job:
pot = [[1,2,3,4],[5,6,7,8]]
val = []
for sublist in pot:
temp = []
for n in range (1, len(sublist)):
temp.append((sublist[n-1], sublist[n]))
val.append(temp)
print val
prints
[[(1, 2), (2, 3), (3, 4)], [(5, 6), (6, 7), (7, 8)]]
I'm new to Python. Just started learning it because I'm working on a project that requires is, but I think this solves your question.
pot = [[1,2,3,4],[5,6,7,8]]
inner = []
val = []
a = 0
b = 0
for L in pot:
for x in range(len(L)):
if x>0:
a = L[x-1]
b = L[x]
inner.append((a,b))
val.append(inner)
inner = []
print val
My output running python 2.7 is:
[[(1, 2), (2, 3), (3, 4)], [(5, 6), (6, 7), (7, 8)]]
I'm brand new to Scala, having had very limited experience with functional programming through Haskell.
I'd like to try composing a list of all possible pairs constructed from a single input list. Example:
val nums = List[Int](1, 2, 3, 4, 5) // Create an input list
val pairs = composePairs(nums) // Function I'd like to create
// pairs == List[Int, Int]((1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 1) ... etc)
I tried using zip on each element with the whole list, hoping that it would duplicate the one item across the whole. It didn't work (only matched the first possible pair). I'm not sure how to repeat an element (Haskell does it with cycle and take I believe), and I've had trouble following the documentation on Scala.
This leaves me thinking that there's probably a more concise, functional way to get the results I want. Does anybody have a good solution?
How about this:
val pairs = for(x <- nums; y <- nums) yield (x, y)
For those of you who don't want duplicates:
val uniquePairs = for {
(x, idxX) <- nums.zipWithIndex
(y, idxY) <- nums.zipWithIndex
if idxX < idxY
} yield (x, y)
val nums = List(1,2,3,4,5)
uniquePairs: List[(Int, Int)] = List((1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5))
Here's another version using map and flatten
val pairs = nums.flatMap(x => nums.map(y => (x,y)))
List[(Int, Int)] = List((1,1), (1,2), (1,3), (1,4), (1,5), (2,1), (2,2), (2,3), (2,4), (2,5), (3,1), (3,2), (3,3), (3,4), (3,5), (4,1), (4,2), (4,3), (4,4), (4,5), (5,1), (5,2) (5,3), (5,4), (5,5))
This can then be easily wrapped into a composePairs function if you like:
def composePairs(nums: Seq[Int]) =
nums.flatMap(x => nums.map(y => (x,y)))