How to create an Array for Tuples in Scala? - arrays

Im trying to create an empty Array to store coordinates of an object in an Tuple which is then stored in an Array.
When I try:
var walls = Array[Tuple2]()
Im getting this error message:
kinds of the type arguments (Tuple2) do not conform to the expected kinds of the type parameters (type T).
[error] Tuple2's type parameters do not match type T's expected parameters:
[error] class Tuple2 has two type parameters, but type T has none
[error] var walls = Array[Tuple2]()
Is there any possibility to do this?

Tuple2 is a type constructor (of kind [*, *] => *).
Array is a type constructor too (of kind [*] => *).
You have to apply Tuple2 to two types (of kind *) in order to make it suitable as an argument of Array.
That's why Array[(Int, Int)] aka Array[Tuple2[Int, Int]] is working while Array[Tuple2] is not.

Okay I found a way:
var walls = Array[(Int, Int)]()

Related

TypeScript object Array type definition

What is the difference between this two type definitions?
type objectArray = [object]
type objectArray = object[]
[object] is a tuple. It's the type of an array with a single value in it, and the value must be an object.
object[] is the same as Array<object>. It's the type of an array with any number of values, where any such values must be object.
All tuples are arrays, but a tuple is a more restrictive type of array, with a specified number of elements.

Understanding syntax for an array of tuples in Swift

I'm trying to understand syntax for arrays of tuples in Swift:
If I create a tuple:
var gameScore: (points: Int, player: String)
I can assign values like this:
gameScore = (1700, "Lisa")
And create an array of this tuple:
var gameScores = [gameScore]
I can append to the array this way:
gameScores.append((1650, "Bart"))
And this way:
gameScore = (1600, "Maggie")
gameScores += [gameScore]
But not this way:
gameScores += [(1600, "Maggie")]
Playground error is:
Playground execution failed: error: Tuples Playground.playground:38:1: error: cannot convert value of type '[(points: Int, player: String)]' to expected argument type 'inout _'
gameScores += [(1600, "Maggie")]
However, this way works:
gameScores += [(points: 1600, player: "Maggie")]
Yes – I have code above that will work, but I'm trying to figure out what I'm not understanding in the failing syntax. Elements don't need to be named for the .append() method, but they need to be named for += [()].
The Swift type inference system is being stretched to the point of breaking here. Swift is having trouble inferring the type of [(1600, "Maggie")] in your example. If you give it a little more information, your example will compile:
gameScores += [(1600, "Maggie") as (points: Int, player: String)]
gameScores += [(1600, "Maggie")] as [(points: Int, player: String)]
and
gameScores = gameScores + [(1600, "Maggie")]
all compile.
It seems Swift is having trouble inferring the type when += is involved.
Looking at the definition of +=:
func +=<C : Collection>(lhs: inout Array<C.Iterator.Element>, rhs: C)
shows that the types of the lhs and rhs are different. Swift is having trouble reconciling the types of the lhs and the rhs from the information given. It seems to be starting with the rhs and then concludes that the type of the lefthand side is inout _ and it tries to reconcile that with the type of gameScores which is [(points: Int, player: String)]. Should it be able to infer the types? Perhaps, but in this case, since you have an easy workaround, I say give the compiler a break and give it the explicit type information and make its job easier:
gameScores += [(points: 1600, player: "Maggie")]

Cannot assign to "" in "self" - Working with Tuples in Swift

I have to classes: FirstViewController and PlanGenerator.
PlanGenerator has a method called getPlanForIndex (day:Int) -> ([PlanElement], [PlanElement])?. It is returning two different Arrays, both containing Object of Plan Element.
getPlanForIndex (day:Int) -> ([PlanElement], [PlanElement])? {
// Do some work and fill arrays
return (firstArray, secondArray)
}
In the FirstViewController I've created two Properties:
let plan:[PlanElement] = [PlanElement]()
let planGen:PlanGenerator = PlanGenerator()
FirstViewControllerhas a method called:
func prepareView () {
plan = planGen.getPlanForIndex(dayIndex)
}
But when I want to call this, I get the error message:
Cannot assign to 'plan' in 'self'
First, your plan member is a constant (declared with let), and you're assigning to it outside of init. If you want to assign to it after initialization, it needs to be declared with var.
Also, your getPlanForIndex returns a tuple, and you're assigning it to a member of singular (not tuple) type. If you want to assign one part of a tuple only, do it like this:
(plan, _) = planGen.getPlanForIndex(dayIndex)
That assigns a tuple to a tuple, satisfying the compiler, but discards the second element.
If you instead want plan to be a tuple, you'll have to declare and initialize it as such. Looks from the comments like you figured out a way to do that, but here's a way with minimal typing (in either sense of the word):
var plan: ([PlanElement], [PlanElement]) = ([], [])
(Once you've declared the type of array, [] is understood to be an empty array of that type. Just var plan = ([], []) leaves the type ambiguous.)

Scala BigInt Array

I'm trying to solve this problem http://projecteuler.net/problem=62 and I am getting hung up on this error:
euler.scala:10: error: type mismatch;
found : Array[Any]
required: Array[Int]
Note: Any >: Int, but class Array is invariant in type T.
You may wish to investigate a wildcard type such as `_ >: Int`. (SLS 3.2.10)
master(perm) = if (master.contains(perm)) master(perm) :+ cube else Array(cube)
^
one error found
The problem may be because of the BigInt trying to be stored in an Array, but aparently there is no such thing as an array with Array[BigInt]
Below is my code:
import scala.util.control.Breaks._
var m = new scala.collection.mutable.LinkedHashMap[String,Array[Int]]
var master = m.withDefaultValue(Array.empty[Int])
val range = 345 to 9999
range.foreach { n =>
val cube = BigInt(n) * n * n
val perm = cube.toString.map(_.asDigit).mkString("")
master(perm) = if (master.contains(perm)) master(perm) :+ cube else Array(cube)
}
master.values.foreach { value =>
if (value.length >= 5) {
println (Math.cbrt(value(0)))
break
}
}
cube is of type BigInt. So Array(cube) is of type Array[BigInt]
The type of master(perm) is Array[Int], and you are trying to do
Array[Int] :+ BigInt => Array[Int], which does not work.
Suggestion: Make all your arrays of type BigInt.
So:
var m = new scala.collection.mutable.LinkedHashMap[String,Array[BigInt]]
var master = m.withDefaultValue(Array.empty[BigInt])
Also consider using a List, instead of an array. That :+ operator will allocate a new array each time. If you use Lists, they are smarter, will perform these immutable operations more efficiently.
There is Array[BigInt], but that is different than Array[Int]. In fact, the common supertype of BigInt and Int is Any, which is why that's appearing in your error messages: when you append cube, which is a BigInt to master(perm), which is and Array[Int], you'll get an Array which has both Int and BigInt, and the only type that supports both is Array[Any].

Is Array[String] not a subclass of Seq[String] in Scala?

I wrote a method that accepts objects of all subclasses of Seq[String]. Unfortunately it won't accept an object of the type Array[String]. Is Array[String] not a subclass of Seq[String]?
scala> def test[T <: Seq[String]](x: T) = {}
test: [T <: Seq[String]](x: T)Unit
scala> val data = "This is a test string"
data: java.lang.String = This is a test string
scala> test(data.split(" "))
<console>:10: error: inferred type arguments [Array[java.lang.String]] do not conform to method test's type parameter bounds [T <: Seq[String]]
test(data.split(" "))
No, Array[String] translates to regular JVM arrays, like the ones you see in Java: String[].
The reason why you see all the operations on Array[String] that you see on other Scala Seq collections is that there is an implicit conversion from Array[T] to ArrayOps[T].
Do this:
def test[T <% Seq[String]](x: T) = {}
This is called a view bound. It means that T should either be a subtype of Seq[String] or there should exist an implicit conversion in scope which converts T into a Seq[String]. Behind the scenes, the compiler actually adds an implicit parameter to test, so this method becomes:
scala> def test[T <% Seq[String]](x: T) = {}
test: [T](x: T)(implicit evidence$1: T => Seq[String])Unit
This implicit evidence$1 is the function which now acts as the implicit conversion from T to Seq[String] within the body of the method.
The sources (or the API docs) state, that Array is defined as
final class Array[T] extends Serializable with Cloneable
That is, it is not a subtype of Seq. However, the docs also mention an implicit conversion WrappedArray, where the latter is a subset of Seq.

Resources