I am developing a scala script that gives all distinct combinations of elements of an array.
For example, assume we have the Array(1,3,6,7). So, the needed results should be like : Array((1,3),(1,6),(1,7),(3,6),(3,7),(6,7))
val test : Array[Int] = Array(1,3,6,7)
val result = test.distinct.combinations(2).flatMap{ case Array(a,b) =>
Array((a,b))
}
println(result)
But this code does not print the needed result.
EDIT
For added need, the initial table should have strings and not integers(this was just for operations tests). Asuume that I have the list val test = List("test", "tabdc", "efjh", "hlmn") And as proposed by @Luis Miguel Mejía Suárez, I generated all combinaisons
val result: List[(String, String)] = List((test,tabdc), (test,efjh), (test,hlmn), (tabdc,efjh), (tabdc,hlmn), (efjh,hlmn))
using
val result = test.distinct.combinations(2).collect {
case a :: b :: Nil =>
(a, b)}.toList
Now, I should compare each couple generated by these pieces of code to construct a string according to these rules :
- two parts can be joined when the last character of the first part is equal to the first character of the second part.
- when combining two parts, only one copy of the linking character is kept
- The returned String should begin with
Aand finish withZ. So if there is no possible combination the result will beAZ
In other words:
- for the couple
(test,tabdc): we havetestis ended bytandtabdcbegin witht. So, they should be added as "testabdc" - for the couple
((efjh,hlmn)): we haveefjhis ended byhandhlmnbegin withh. So, they should be added as : "efjhlmn"
In this example: the final result should be AtestabdcefjhlmnZ (the concatenation between all joined parts)
How can I do it, please?
CodePudding user response:
Okey, multiple things are happening in this snippet.
combinationsreturns anIteratorwhich is lazy by nature, so that is why you don't see any output; because it hasn't computed anything at all.
You may try to solve that by adding atoArrayat the end, but that will give you a wrong output.Arraysshould not be used, especially not while learning, they are useful for Java interop and performance tunning, but normal Scala code shouldn't wonder about those things.
The list of reasons for not usingArraysinclude: they are mutable, they are invariant, they are not part of the collections hierarchy, theirequalsis by reference instead of by value, and theirtoStringdoesn't pretty print the contents of theArray; that is why adding atoArrayat the end won't fix the problem. Thus, rather we should useListeverywhere.No need for that
flatMapa simplemapwould work. However, sincecombinationscan't guarantee the type safety of its output, is better to usecollectjust to be safe.
Thus the final code would be:
val test = List(1, 3, 6, 7)
val result = test.distinct.combinations(2).collect {
case a :: b :: Nil =>
(a, b)
}.toList
You can see the code running here.
CodePudding user response:
result is Iterator which is lazy, so one way to print is materialize it using toSeq for example:
println(result.toSeq) // prints List((1,3), (1,6), (1,7), (3,6), (3,7), (6,7))
