Why do I get the following different results when converting a vector using either tuple or Tuple?
julia> a = [1, 2, 3]
3-element Vector{Int64}:
1
2
3
julia> tuple(a)
([1, 2, 3],)
julia> Tuple(a)
(1, 2, 3)
Broadcasting gives the same result though:
julia> tuple.(a)
3-element Vector{Tuple{Int64}}:
(1,)
(2,)
(3,)
julia> Tuple.(a)
3-element Vector{Tuple{Int64}}:
(1,)
(2,)
(3,)
(The latter is not so surprising as it just converts single numbers to tuples.)
(This is Julia 1.6.1.)
Tuple is a type and as with all collections in Julia base, if you pass another collection to it, it creates an instance of that type from the contents of the other collection. So Tuple([1, 2, 3]) constructs a tuple of the values 1, 2 and 3 just like Set([1, 2, 3]) constructs a set of those same values. Similarly, if you write Dict([:a => 1, :b => 2, :c => 3]) you get a dict that contains the pairs :a => 1, :b => 2 and :c => 3. This also works nicely when the argument to the constructor is an iterator; some examples:
julia> Tuple(k^2 for k=1:3)
(1, 4, 9)
julia> Set(k^2 for k=1:3)
Set{Int64} with 3 elements:
4
9
1
julia> Dict(string(k, base=2, pad=2) => k^2 for k=1:3)
Dict{String, Int64} with 3 entries:
"10" => 4
"11" => 9
"01" => 1
So that's why Tuple works the way it does. The tuple function, on the other hand, is a function that makes a tuple from its arguments like this:
julia> tuple()
()
julia> tuple(1)
(1,)
julia> tuple(1, "two")
(1, "two")
julia> tuple(1, "two", 3.0)
(1, "two", 3.0)
Why have tuple at all instead of just having Tuple? You could express this last example as Tuple([1, "two", 3.0]). However, that requires constructing a temporary untyped array only to iterate it and make a tuple from its contents, which is really inefficient. If only there was a more efficient container type that the compiler can usually eliminate the construction of... like a tuple. For that we'd write Tuple((1, "two", 3.0)). Which works, but is completely redundant since (1, "two", 3.0) is already the tuple you wanted. So why would you use tuple? Most of the time you don't, you just use the (1, "two", 3.0) syntax for constructing a tuple. But sometimes you want an actual function that you can apply to some values to get a tuple of them—and tuple is that function. You can actually make an anonymous function that does this pretty easily: (args...) -> (args...,). You can just think of tuple as a handy abbreviation for that function.
Related
Just found something rather not comprehensible while converting a List into a variable lengh argument. In the worksheet i get this:
case class Sequence[A](as: A*)
Sequence(List(1,2,3): _*) //res1: Sequence[Int] = Sequence(List(1, 2, 3))
Sequence(1,2,3) //res3: Sequence[Int] = Sequence(WrappedArray(1, 2, 3))
My understand is that (1) and (2) should be the same, and indeed the Type is both Sequence[Int]
What is weird is that one is a WrappedArray(1, 2, 3) and the other a List(1, 2, 3) inside the sequence.
I am not sure to understand that
Any explanation for the difference ?
I wanted to write a Scala program that takes command-line args as list input and provide the output list without duplicates.
I want to know the custom implementation of this without using any libraries.
Input : 4 3 7 2 8 4 2 7 3
Output :4 3 7 2 8
val x= List(4, 3, 7, 2, 8, 4, 2, 7, 3)
x.foldLeft(List[Int]())((l,v)=> if (l.contains(v)) l else v :: l)
if you can't use contains you can do another fold
x.foldLeft(List[Int]())((l,v)=> if (l.foldLeft(false)((contains,c)=>if (c==v ) contains | true else contains | false)) l else v :: l)
Here's a way you could do this using recursion. I've tried to lay it out in a way that's easiest to explain:
import scala.annotation.tailrec
#tailrec
def getIndividuals(in: List[Int], out: List[Int] = List.empty): List[Int] = {
if(in.isEmpty) out
else if(!out.contains(in.head)) getIndividuals(in.tail, out :+ in.head)
else getIndividuals(in.tail, out)
}
val list = List(1, 2, 3, 4, 5, 4, 3, 5, 6, 0, 7)
val list2 = List(1)
val list3 = List()
val list4 = List(3, 3, 3, 3)
getIndividuals(list) // List(1, 2, 3, 4, 5, 6, 0, 7)
getIndividuals(list2) // List(1)
getIndividuals(list3) // List()
getIndividuals(list4) // List(3)
This function takes two parameters, in and out, and iterates through every element in the in List until it's empty (by calling itself with the tail of in). Once in is empty, the function outputs the out List.
If the out List doesn't contain the value of in you are currently looking at, the function calls itself with the tail of in and with that value of in added on to the end of the out List.
If out does contain the value of in you are currently looking at, it just calls itself with the tail of in and the current out List.
Note: This is an alternative to the fold method that Arnon proposed. I personally would write a function like mine and then maybe refactor it into a fold function if necessary. I don't naturally think in a functional, fold-y way so laying it out like this helps me picture what's going on as I'm trying to work out the logic.
What does to function do in:
rdd.flatMap(x => x.to(3))
?
rdd is composed of {1, 2, 3, 3} and the above function returns {1, 2, 3, 2, 3, 3, 3}
I have been googling "scala number to function" and its variants, but can't seem to find what it does.
To function
To create a Range in Scala, use the predefined methods to and by.
Example:
1 to 3 will give Range(1, 2, 3)
What does to function do in RDD
a) Looking into map function:
sc.range(1L, 6L).map(x => x to 3).collect.foreach(println)
This prints
NumericRange(1, 2, 3)
NumericRange(2, 3)
NumericRange(3)
NumericRange() // 4 to 3 returns an empty Range
NumericRange() // 5 to 3 returns an empty Range
b) Looking into flatMap function:
sc.range(1L, 6L).flatMap(x => x to 3).collect.foreach(println)
This prints
1
2
3
2
3
3
It combines mapping and flattening. flatMap takes a function that works on the nested lists and then concatenates the results back together.
An important thing to understand about flatMap is that anything that looks like an empty array will disappear. so NumericRange() doesn't appears in flatMap result .
rdd.flatMap(x => x.to(3)) works as follows:
1. rdd.map(x => x.to(3))
a) fetch the first element of {1, 2, 3, 3}, that is 1
b) apply to x => x.to(3), that is 1.to(3),
that is also explained as 1 to 3, it will generate the range {1, 2, 3}
c) fetch the second element of {1, 2, 3, 3}, that is 2
d) apply to x => x.to(3), that is 2.to(3), that is also explained as 2 to 3,
it will generate the range {2, 3}
e) repeat above, 3 to 3 will get {3}, the final 3 will get {3}
f) so finally, you get {{1, 2, 3}, {2, 3}, {3}, {3}}
2. flatMap is combination of map and flattern
so flatmap will make {{1, 2, 3}, {2, 3}, {3}, {3}} become {1, 2, 3, 2, 3, 3, 3}
So, x.to(y) just to generate a range, [x, y], you can use repl to verify it.
C:\Windows\System32>scala
Welcome to Scala version 2.10.6 (Java HotSpot(TM) Client VM, Java 1.7.0_55).
Type in expressions to have them evaluated.
Type :help for more information.
scala> 2 to 5
res0: scala.collection.immutable.Range.Inclusive = Range(2, 3, 4, 5)
I have some experience with R language and now I wanted to try Scala language. In R language I can assign one value to many elements of a vector, e.g.
(xs <- 1:10)
#[1] 1 2 3 4 5 6 7 8 9 10
k <- 3
xs[1:k] <- xs[k+1]
xs
# 4 4 4 4 5 6 7 8 9 10
It assigns value of k+1 element to all elements of indices from 1 to k. Is it also possible to do it without a loop in Scala (I mean Array in Scale)? I know there is slice method, but it only returns values of an Array, one cannot modify elements of the Array using this method.
What is even more, should I use Array or ArrayBuffer if I only want to change values of elements and I do not want to add/remove elements from a collection?
Check out the java.util.Arrays.fill methods.
scala> val xs = (1 to 9).toArray
xs: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> val k = 6
k: Int = 6
scala> java.util.Arrays.fill(xs, 0, k, xs(k))
scala> xs
res10: Array[Int] = Array(7, 7, 7, 7, 7, 7, 7, 8, 9)
For your second question, if not resizing the collection but editing the elements, stick with array. ArrayBuffer is much like the Java ArrayList, it resizes it self when it needs to, so insertion is amortized constant, not just constant.
For your first question, I'm not aware of any method in the collections library that would allow you to do this. It's obviously syntactic sugar for looping, so if you really care (do you really find yourself needing to do this often?), you can define an implicit class and yourself define a method which loops, and then use that. Write a comment if you would like to see example of such code, otherwise try doing it yourself, it's gonna be good training.
Scala has the Range class. You can convert the Range to an Array if you wish.
scala> val n = 10
n: Int = 10
scala> Range(1,n)
res22: scala.collection.immutable.Range = Range(1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> res22.toArray
res23: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
│
ArrrayBuffer has constant time update and would be good for updating values.
I have a file containing a line
4 3 2
5 6 7
9 8 2
I am splitting the line by tab and then want to break the content into 2 pieces
What is the way to convert each line of input to 2 seperate tuple as following-
(4 3 2) = (4 1 2) & (3 1 2)
I am assuming that:
each tab-separated line consists of three elements
elements within each line are separated with exactly one space character
each line needs to be converted to a tuple of tuples
In case I got any of these wrong (e.g. there can be more than 3 elements in each row or you need different structures than tuples) it can be easily adapted.
val file = "4 3 2\t5 6 7\t9 8 2"
val lines = file.split("\t").map(line => line.split(" ").toList)
val newLines = lines.map({
case a :: b :: c :: Nil => ((a, "1", c), (b, "1", c))
})
newLines.map(println)
// ((4, 1, 2), (3, 1, 2))
// ((5, 1, 7), (6, 1, 7))
// ((9, 1, 2), (8, 1, 2))
EDIT:
This answer was based on the logic that you wrote initially in your question and which said that you want this kind of map: ((a b c) => (a 1 c) (b 1 c)). I can see now that you removed that part so I'm not sure if the logic in my solution is right, but now that you have the basic skeleton you can modify as you need.