What would be the best way to achieve the following please? I have two lists:
val l1 = List("a", "b")
val l2 = List(1, 2)
and I would like to generate this:
List (
List(('a', 1), ('b', 1)),
List(('a', 1), ('b', 2)),
List(('a', 2), ('b', 1)),
List(('a', 2), ('b', 2))
)
Which is basically the first list combined with the second to create a list of list of tuples? Was thinking of using a foldLeft with a sliding(2,2) to get my results but cannot just get the right result.
The solution should work with any size and type, like List('a', 'b', 'c') and List("1", "2")
Thanks
Furthermore there is also a method for combinations: scala> List(1,2,3).combinations(2).mkString(" ") res4: String = List(1, 2) List(1, 3) List(2, 3) Regarding your implementation I would say three things:
Multiple Parameter Lists (Currying) Methods may have multiple parameter lists. Here is an example, as defined on the TraversableOnce trait in Scala’s collections API: def foldLeft[B](z: B)(op: (B, A) => B): B. foldLeft applies a two-parameter function op to an initial value z and all elements of this collection, going left to right.
In order to concatenate two lists we need to utilize concat () method in Scala. In above syntax, l1 is list1 and l2 is list2. Below is the example to concat two lists in scala. Here, the identical elements are not removed.
Scala - Lists. Scala Lists are quite similar to arrays which means, all the elements of a list have the same type but there are two important differences. First, lists are immutable, which means elements of a list cannot be changed by assignment. Second, lists represent a linked list whereas arrays are flat.
Trickier than I thought! The first step is to calculate the n-times Cartesian product of l2, which can be done using a combination of List.fill
, combinations
, and permutations
(I have a hard time believing that there is no easier way to do this, but I haven't found any):
def prod[T](lst: List[T], n: Int) = List.fill(n)(lst).flatten.combinations(n).flatMap(_.permutations)
The value of n
is determined by the size of list l1
. In your example prod(l2, 2)
will give us List(List(1, 1), List(1, 2), List(2, 1), List(2, 2))
. The rest is just an application of map
and zip
. Together, we have
prod(l2, l1.size).map(l1.zip(_))
Output for l1 = List('a', 'b', 'c'), l2 = List("1", "2")
:
List((a,1), (b,1), (c,1))
List((a,1), (b,1), (c,2))
List((a,1), (b,2), (c,1))
List((a,2), (b,1), (c,1))
List((a,1), (b,2), (c,2))
List((a,2), (b,1), (c,2))
List((a,2), (b,2), (c,1))
List((a,2), (b,2), (c,2))
The best way is to use a for comprehension. Much cleaner than the accepted solution IMO :)
for {
i1 <- List('a', 'b', 'c')
i2 <- List(1, 2)
} yield List(i1, i2)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With