Scalactic: convert an Iterable to Every - scala

Using scalactic, one can convert an Every to a List like this:
scala> Every(1,2,3).toList
res6: List[Int] = List(1, 2, 3)
How can I perform the reverse operation, though, i.e. try to convert a List or an Iterable to an Every? Is there a built-in method that does this?

Simply:
val everyOpt: Option[Every[Int]] = Every.from(List(1, 2, 3))
If the list is known to be non empty:
val every: Every[Int] = Every.from(List(1, 2, 3)).get

Related

How to convert a Scala Array to ArrayBuffer?

I see that a Scala Array can be easily converted to List, Seq etc, using the s.toList or s.toSeq. Now, I would like to convert an array to a bufferarray. How would I do it?
There's a generic method to that can convert between arbitrary collection types.
Array(1, 2, 3).to[ArrayBuffer]
Or from Scala 2.13 onwards:
Array(1, 2, 3).to(ArrayBuffer)
Use Iterable: _*:
val arr = Array(1,2,3)
arr: Array[Int] = Array(1, 2, 3)
val buf = collection.mutable.ArrayBuffer(arr: _*)
buf: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3)
The _* means to unpack the Iterable elements. So arr: _* unpacks the elements of arr into a variable length list - which is an acceptable parameter list for `ArrayBuffer.
please try Array(1, 2, 3).toBuffer
For anyone that is now looking for the answer, the answer which has been accepted is deprecated. If you will try to execute it then it will execute it successfully but will give you a warning message. So either you can refer Claire Hou answer or you can use
Array('a','b','c').toIndexedSequence

Using `Seq::fill` with an existing sequence

I would want to fill a Seq[Seq[Int]] instance with an existing Seq[Int] by using the method fill(n1, n2)(element : A) of the Object Seq, as detailed in the documentation : http://www.scala-lang.org/api/2.12.3/scala/collection/Seq$.html#fillA(elem:=>A):CC[CC[A]]
So I wrote this call :
Seq.fill(width, width)(_random_values.) , with _random_values the existing Seq[Int].
The problem is that the parameter of the second list of fill is an element, not a Seq. So, what could I type to iterate on each _random_values's integers AND to execute the Seq.fill for each current integer ?
Seq.fill is more appropriate to create a Seq base on a static value. For your use case Seq.grouped might be a better fit:
val values: Seq[Int] = List(1, 2, 3, 4)
val result: Seq[Seq[Int]] = values.grouped(2).toSeq
result.foreach(println)
/*
List(1, 2)
List(3, 4)
*/

Index with Many Indices

Is there a quick scala idiom to have retrieve multiple elements of a a traversable using indices.
I am looking for something like
val L=1 to 4 toList
L(List(1,2)) //doesn't work
I have been using map so far, but wondering if there was a more "scala" way
List(1,2) map {L(_)}
Thanks in advance
Since a List is a Function you can write just
List(1,2) map L
Although, if you're going to be looking things up by index, you should probably use an IndexedSeq like Vector instead of a List.
You could add an implicit class that adds the functionality:
implicit class RichIndexedSeq[T](seq: IndexedSeq[T]) {
def apply(i0: Int, i1: Int, is: Int*): Seq[T] = (i0+:i1+:is) map seq
}
You can then use the sequence's apply method with one index or multiple indices:
scala> val data = Vector(1,2,3,4,5)
data: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3, 4, 5)
scala> data(0)
res0: Int = 1
scala> data(0,2,4)
res1: Seq[Int] = ArrayBuffer(1, 3, 5)
You can do it with a for comprehension but it's no clearer than the code you have using map.
scala> val indices = List(1,2)
indices: List[Int] = List(1, 2)
scala> for (index <- indices) yield L(index)
res0: List[Int] = List(2, 3)
I think the most readable would be to implement your own function takeIndices(indices: List[Int]) that takes a list of indices and returns the values of a given List at those indices. e.g.
L.takeIndices(List(1,2))
List[Int] = List(2,3)

Convert tuple to a List of first item

Say I have a method that returns this.
Vector[ (PkgLine, Tree) ]()
I want to convert this to a List of PkgLines. I want to drop the Tree off. I'm not seeing anything in the scala library that would allow me to do this. Anybody have any simple ideas? Thanks.
val list = vector.map(_._1).toList
If you have a Tupel t, you can access its first element using t._1. So with the map operation, you're effectively throwing away the trees, and store the PkgLines directly. Then you simply convert the Vector to List.
Using map with a selector of the first element of the pair works:
scala> val v = Vector[(Int,String)]((5,"5"), (42,"forty-two"))
v: ... = Vector((5,5), (42,forty-two))
scala> v.map(_._1).toList
resN: List[Int] = List(5, 42)
Alternatively, you can use unzip:
scala> val (ints,strings) = v.unzip
ints: scala.collection.immutable.Vector[Int] = Vector(5, 42)
strings: scala.collection.immutable.Vector[String] = Vector(5, forty-two)
scala> ints.toList
resN: List[Int] = List(5, 42)

Scala: Yielding from one type of collection to another

Concerning the yield command in Scala and the following example:
val values = Set(1, 2, 3)
val results = for {v <- values} yield (v * 2)
Can anyone explain how Scala knows which type of collection to yield into? I know it is based on values, but how would I go about writing code that replicates yield?
Is there any way for me to change the type of the collection to yield into? In the example I want results to be of type List instead of Set.
Failing this, what is the best way to convert from one collection to another? I know about _:*, but as a Set is not a Seq this does not work. The best I could find thus far is val listResults = List() ++ results.
Ps. I know the example does not following the recommended functional way (which would be to use map), but it is just an example.
The for comprehensions are translated by compiler to map/flatMap/filter calls using this scheme.
This excellent answer by Daniel answers your first question.
To change the type of result collection, you can use collection.breakout (also explained in the post I linked above.)
scala> val xs = Set(1, 2, 3)
xs: scala.collection.immutable.Set[Int] = Set(1, 2, 3)
scala> val ys: List[Int] = (for(x <- xs) yield 2 * x)(collection.breakOut)
ys: List[Int] = List(2, 4, 6)
You can convert a Set to a List using one of following ways:
scala> List.empty[Int] ++ xs
res0: List[Int] = List(1, 2, 3)
scala> xs.toList
res1: List[Int] = List(1, 2, 3)
Recommended read: The Architecture of Scala Collections
If you use map/flatmap/filter instead of for comprehensions, you can use scala.collection.breakOut to create a different type of collection:
scala> val result:List[Int] = values.map(2*)(scala.collection.breakOut)
result: List[Int] = List(2, 4, 6)
If you wanted to build your own collection classes (which is the closest thing to "replicating yield" that makes any sense to me), you should have a look at this tutorial.
Try this:
val values = Set(1, 2, 3)
val results = for {v <- values} yield (v * 2).toList