Reputation: 9
I am trying to convert a var assignment to a val assignment. Currently my code is
// Numerical vectorizing for normalization
var normNumericalColNameArray: Array[String] = Array()
if (!continousPredictors.sameElements(Array(""))) {
if (paramStandardize) {
println("Apply standardization")
stages += new VectorAssembler().setInputCols(continousPredictors).setOutputCol(NumericalFeaturesCol)
stages += new StandardScaler()
.setWithMean(true)
.setWithStd(true)
.setInputCol(NumericalFeaturesCol)
.setOutputCol(StandardizedNumericalFeaturesCol)
normNumericalColNameArray = Array(StandardizedNumericalFeaturesCol)
} else {
println("Not apply standardization")
stages += new VectorAssembler().setInputCols(continousPredictors).setOutputCol(NumericalFeaturesCol)
normNumericalColNameArray = Array(NumericalFeaturesCol)
}
}
stages += new VectorAssembler().setInputCols(normNumericalColNameArray ++ oneHotCatColNamesArray).setOutputCol(FeaturesCol)
and I want to do something like this
val normNumericalColNameArray =
if (continousPredictors.nonEmpty && paramStandardize) {
println("Apply standardization")
stages += new VectorAssembler().setInputCols(continousPredictors).setOutputCol(NumericalFeaturesCol)
stages += new StandardScaler()
.setWithMean(true)
.setWithStd(true)
.setInputCol(NumericalFeaturesCol)
.setOutputCol(StandardizedNumericalFeaturesCol)
Array(StandardizedNumericalFeaturesCol)
} else if (continousPredictors.nonEmpty){
println("Not apply standardization")
stages += new VectorAssembler().setInputCols(continousPredictors).setOutputCol(NumericalFeaturesCol)
Array(NumericalFeaturesCol)
}
stages += new VectorAssembler().setInputCols(normNumericalColNameArray ++ oneHotCatColNamesArray).setOutputCol(FeaturesCol)
and I run into this error
value ++ is not a member of Any
stages += new VectorAssembler().setInputCols(normNumericalColNameArray ++ oneHotCatColNamesArray).setOutputCol(FeaturesCol)
I am trying to return the Array from the if condition into my Val normNumericalColNameArray. Can somebody please help?
Upvotes: 0
Views: 58
Reputation: 20561
For an if
expression, the resulting type is the least-upper-bound of the branches. If there's no final else
, there's an implicit
else () // where () is the singleton value of the Unit type
So in your if {} else if
without a final else
, the overall expression will have the type of whatever the least-upper-bound of Array[String]
, Array[String]
, and Unit
is, which is Any
, which then becomes the type inferred for normNumericalColNameArray
.
As Tim and gifa note, you can fix this by adding a final else
clause. There's also no need to hoist the inner if
into the outer condition check:
val normNumericalColNameArray =
if (continousPredictors.nonEmpty) {
stages += new VectorAssembler().setInputCols(continousPredictors).setOutputCol(NumericalFeaturesCol)
if (paramStandardize) {
println("Apply standardization")
stages += new StandardScaler()
.setWithMean(true)
.setWithStd(true)
.setInputCol(NumericalFeaturesCol)
.setOutputCol(StandardizedNumericalFeaturesCol)
Array(StandardizedNumericalFeaturesCol)
} else {
println("Not apply standardization")
Array(NumericalFeaturesCol)
}
} else {
Array[String]()
}
Upvotes: 1
Reputation: 86
The problem is in the if statement. You have:
val normNumericalColNameArray = {
if (condition1){
Array[String]()
}
else if (condition2){
Array[String]()
}
}
Now, your variable has type Any because if condition1 is not true and condition2 is not true, then your if statement (function) doesn't return anything: you actually made a partial function. Try adding a final else statement, like:
val normNumericalColNameArray = {
if (condition1){
Array[String]()
}
else if (condition2){
Array[String]()
}
else{
Array[String]()
}
}
It will work then. Also, I would recommend to make your normNumericalColNameArray
a lazy val, so to be evaluated only when it is required, since you are modifying stages
in the if statement.
Upvotes: 0
Reputation: 27421
The problem is that there is an if
without an else
block, so the result could be nothing (Unit
). Just add an else
clause:
} else if (continousPredictors.nonEmpty) {
println("Not apply standardization")
stages += new VectorAssembler().setInputCols(continousPredictors).setOutputCol(NumericalFeaturesCol)
Array(NumericalFeaturesCol)
} else {
Array()
}
But Array
is a Java type, so prefer to use Vector
or List
if possible.
Upvotes: 1