Expression pattern of type 'Double' cannot match values of type '[Double]'? - swift

if gpa[12] < gpa[1] {
print(gpa[12])
} else {
switch gpa {
case gpa[1]:
print(gpa)
}
}
I don't understand how to fix or what this may mean? I am on Xcode 9
What I am doing is trying to have values of GPA switched. I am using cases to switch out. Sorry, I'm new and it's hard for me to explain what I mean.

switch gpa
here gpa is an array of doubles, [Double]
case gpa[1]:
here the case is using a single Double value.
What the error message is telling you is that you can not ask a switch to compare a Double value ( gpa[1] ) to the entire array of gpa's ( gpa ) because they are different types.

Related

Binary operator '+' cannot be applied to operands of type 'Int' and '[Int]'

I'm trying to write code that will update my array and give total pay based on the daily pay. I'm getting an error about binary operators so how do I fix this line code so that doesn't happen.
for day in stride(from: 1, to: 31, by: 1)
{
dailyPay[day] = [Int(pay)]
pay*=2
if(day==1)
{
totalPay[day] = Int(pay)
}
else
{
totalPay[day] = totalPay[day-1]+dailyPay[day]//The problem is Here
print("\(heade) \(day) \(head) \(dailyPay[day]) \(total) \(totalPay[day])")
}
You don't show the declarations of your variables, but it appears that totalPay is an array of Ints, whereas dailyPay is a two-dimensional array of arrays of Int. So, totalPay[day-1] will be an Int, whereas dailyPay[day] will be an [Int], or an array of Ints. The error you're getting therefore means exactly what it says; you can't use + to add an Int and an array.
From your code, it appears that dailyPay is probably meant to be a plain old array of integers, like totalPay. So you could fix this by changing the declaration, whereever it is, from:
var dailyPay: [[Int]]
to:
var dailyPay: [Int]
Then, change the assignment to:
dailyPay[day] = Int(pay)
and things should work.
Sidenote: Your for loop is needlessly complex. There's no need for stride, when you can just:
for day in 1...31

Left side of mutating operator isn't mutable: 'gpa' is a 'let' constant

I am currently struggling with an error for a homework assignment in my coding class. We are creating a loop that loops through an array of gpa values and then adds it to a variable named totalGradePoints. The problem is that I am coming across an error when the loop runs:
Left side of mutating operator isn't mutable: 'gpa' is a 'let' constant
The error is on this line:
var totalGradePoints = Double()
for gpa in gpaValues {
let averageGPA: Double = gpa += totalGradePoints
}
Here is my full code:
//: Playground - noun: a place where people can play
import UIKit
// You are the university registrar processing a transfer student's transcripts that contains grades that are a mix of letters and numbers. You need to add them to our system, but first you need to convert the letters into grade points.
// Here's an array of the student's grades.
var transferGrades: [Any] = ["C", 95.2, 85, "D", "A", 93.23, "P", 90, 100]
// To prepare for converting the letters to numerical grades, create a function that returns a double, inside which you create a switch that will convert an A to a 95, B to 85, C to 75, D to 65, , P (for passing) to 75. Everything else will be a zero.
func gradeConverter(letterGrade: String) -> Double {
switch letterGrade {
case "A":
return 95
case "B":
return 85
case "C":
return 75
case "D":
return 65
case "P":
return 75
default: // Is this where everything else is zero?
return 0
}
}
// Create a new array called convertedGrades that stores doubles.
var convertedGrades: [Double] = [98.75, 75.5, 60.0, 100.0, 82.25, 87.5]
// Loop through the transferGrades array, inspecing each item for type and sending strings (your letter grades) to the function you just made and storing the returned double in your convertedGrades array. If your loop encounters a double, you can place it directly into the new array without converting it. It it encounters an int, you will need to convert it to a double before storing it. Print the array. (You may notice that some of your doulbes are stored with many zeros in the decimal places. It's not an error, so you can ignore that for now)
for grade in transferGrades {
if let gradeAsString = grade as? String {
gradeConverter(letterGrade: gradeAsString)
} else if let gradeAsDouble = grade as? Double {
transferGrades.append(gradeAsDouble)
} else if let gradeAsInt = grade as? Int {
Double(gradeAsInt)
transferGrades.append(gradeAsInt)
}
}
print(transferGrades)
// Now that we have an array of numerical grades, we need to calculate the student's GPA. Create a new array called GPAValues that stores doubles.
var gpaValues: [Double] = [2.5, 3.0, 4.0, 3.12, 2.97, 2.27]
// Like with the letter conversion function and switch you created before, make a new function called calculateGPA that takes a double and returns a double. Inside your function, create another switch that does the following conversion. Grades below 60 earn zero grade points, grades in the 60s earn 1, 70s earn 2, 80s earn 3, and 90s and above earn 4.
func calculateGPA(gpaValue: Double) -> Double {
switch gpaValue {
case 0..<59:
return 0
case 60...69:
return 1
case 70...79:
return 2
case 80...89:
return 3
case 90..<100:
return 4
default:
return 0
}
}
// Loop through your convertedGrades array and append the grade point value to the GPAValues array. Because your calculateGPA function returns a value, you can use it just like a varialbe, so rather than calculate the grade points and then put that varialbe in your append statement, append the actual function. i.e. myArray.append(myFunction(rawValueToBeConverted))
for gpa in gpaValues {
gpaValues.append(calculateGPA(gpaValue: gpa))
}
// Finally, calculate the average GPA by looping through the GPA and using the += operator to add it to a variable called totalGradePoints. You may need to initialize the variable before using it in the loop. i.e. var initialized = Double()
var totalGradePoints = Double()
for gpa in gpaValues {
let averageGPA: Double = gpa += totalGradePoints
}
// Count the number of elements in the array (by using the count method, not your fingers) and store that number in a variable called numberOfGrades. Pay attention to creating your variables with the right types. Swift will tell you if you're doing it wrong.
var numberOfGrades: Int = gpaValues.count
// Divide the totalGradePoints by numberOfGrades to store in a variable called transferGPA.
var transferGPA: Double = Double(totalGradePoints) / Double(numberOfGrades)
// Using code, add one numerical grade and one letter grade to the transferGrades array that we started with (i.e. append the values rather than manualy writing them into the line at the beginning of this file) and check that your transferGPA value updates. You'll need to append the new grades on the line below the existing transferGrades array so that your changes ripple through the playground.
transferGrades.append(97.56)
transferGrades.append("B")
averageGPA must be define using the var keyword to make it mutable later on when summing up the values.
var averageGPA: Double = 0
for gpa in gpaValues {
averageGPA += gpa
}
averageGPA = averageGPA / Double(gpaValues.count)
Recall the average is calculated by summing up the score and dividing the number of scores.
Defining something with let means that the following will be a constant.
let answer: Int = 42
answer = 43 /* Illegal operation. Cannot mutate a constant */
Left side of mutating operator isn't mutable: 'gpa' is a 'let' constant
The problem is that gpa is a constant, you can't modify its value. And the "+=" operator means "increase gpa's value by totalGradePoints", it is trying to increase the value of gpa. What you probably mean to do is make averageGPA equal the sum of gpa and totalGradePoints. For that you would do this:
let averageGPA: Double = gpa + totalGradePoints

Swift: Can someone explain this syntax `numbers.sort { $0 > $1 }` for me?

First of all, this question is not about "what does $0 mean". I learnt in swift document that $0 is like index.
My question is "How numbers.sort { $0 > $1 } can be used to implement a sort function". I searched for this syntax numbers.sort { $0 > $1 } in some other websites, for example this one. It is apparently not the current version. So I still can't understand what the meaning of it.
print(numbers) //[20, 19, 1, 12]
let sortedNumbers = numbers.sort { $0 > $1 }
print(sortedNumbers) //[20, 19, 12, 1]
Can someone explain this simple piece of code above for me? Like how this simple code $0 > $1 implement the sort function, sorting the numbers from big to small.
I know some about index, and this $0 looks like index, but it only has $0 and $1 two indices. So how can it be used into 4 numbers? According to my knowledge in C++ before, I can't understand the principle in this.
Please make your answer as specific as possible. Thank you!
----------------- Below is edited extra part -------------------
I don't know whether stackoverflow would allow me to edit my question like this, but this extra part is too long, so I can't add it in the comment.
#pbodsk #Paul Richter
So the sort() syntax in swift uses quick sort to deal with sort function?
Actually my question is more about "what is the operating principle of sort{$0 > $1}". I know what you mean above, and I think it's similar with what swift 2.1 document says, but your answer is not what I really want to know. Sorry, my English expression is not very good. Let me try another way.
When I learnt C++ before, there are always some documents to explain what a function's operating principle is or how this function (like sort() here) operate in background. Sort() here needs to compare first and second interchange. In C++, it's like
if numbers[1] < numbers[2]{ //just consider this pseudocode
int k;
k = numbers[1];
numbers[1] = numbers[2];
numbers[2] = k;
}
We can see this process is obvious. In swift, it's like
numbers.sort({(val1: Int, val2: Int) -> Bool in
return val1 > val2
})
Where is it compared? And how is it interchanged? Does return val1 > val2 automatically compare and interchange these two values and return them? Just this one syntax implement these all 3 processes? How? This is what I really want to know. Sorry again for my poor English expression.
#the_UB and #moonvader are both right, but I just thought that I would extend the example from #moonvader a bit, just to show you how we end up with $0 > $1
If you look at the example in "The Swift Programming Language" about Closure Expressions you can see that to sort an array you call the sort method which can then take a function as a parameter.
This function must take two parameters and compare them, and then return a boolean.
So if we have this array:
let numbers = [4, 6, 8, 1, 3]
and this method
func sortBackwards(val1: Int, val2: Int) -> Bool {
print("val1: \(val1) - val2: \(val2)" )
return val1 > val2
}
We can sort the elements like so:
numbers.sort(sortBackwards) //gives us [8, 6, 4, 3, 1]
The sort method will use our sortBackwards method on each of the elements in the array and compare them.
Here's the output of the print
val1: 6 - val2: 4
val1: 8 - val2: 4
val1: 8 - val2: 6
val1: 1 - val2: 4
val1: 3 - val2: 1
val1: 3 - val2: 4
OK, let's reduce that.
Instead of defining a function, we can add that directly as a parameter to the sort method like so:
numbers.sort({(val1: Int, val2: Int) -> Bool in
return val1 > val2
})
And we still end up with [8, 6, 4, 3, 1] (how fortunate!)
OK, the next thing we can do is what in "The Swift Programming Language" (the link above) is called "Infering Type From Context". As we call this method on an array of Ints, Swift can figure out that our val1 and val2 parameters must be Ints too, there's no need for us to tell it. So, lets remove the types. That leaves us with:
numbers.sort({val1, val2 in
return val1 > val2
})
And still the same result.
OK, getting there. The next thing we can do is what in the book is called "Implicit Returns from Single-Expression Closures"
As our comparison can be done in one line there's no need for us to use return. So:
numbers.sort({val1, val2 in val1 > val2})
Still gives us [8, 6, 4, 3, 1]
Finally we're getting to what #moonvader used much much less words to explain :-) namely "Shorthand Argument Names"
As it says in the book:
Swift automatically provides shorthand argument names to inline closures, which can be used to refer to the values of the closure’s arguments by the names $0, $1, $2, and so on.
So, in our example, val1 can be replaced by $0 and val2 can be replaced by $1
Which gives us:
numbers.sort({$0 > $1})
And still we get [8, 6, 4, 3, 1]
We can then continue to use a "Trailing Closure", which means that if the last parameter of a function is a closure, we can add that parameter "outside" the function.
So we end up with:
numbers.sort{$0 > $1}
And the outcome is still [8, 6, 4, 3, 1]
Hope that helps to clarify things.
Here is what all need to know: Sort and Sorted.
To be more specific, Sorting can be two type : Ascending and Descending.
Q - So to do sorting, what do we need?
A - We need two variables to hold two variable(I don't know if it is the correct word)
Hence in this case we have two variable $0 and $1. These both are shorthands to represent left and right variable. Both will help to sort.
">" will do descending.
"<" will do ascending.
From developer.apple.com
Shorthand Argument Names
Swift automatically provides shorthand argument names to inline closures, which can be used to refer to the values of the closure’s arguments by the names $0, $1, $2, and so on.
If you use these shorthand argument names within your closure expression, you can omit the closure’s argument list from its definition, and the number and type of the shorthand argument names will be inferred from the expected function type. The in keyword can also be omitted, because the closure expression is made up entirely of its body:
reversed = names.sort( { $0 > $1 } )
Here, $0 and $1 refer to the closure’s first and second String arguments.
The process of sorting a list consists of repeatedly reordering its elements until nothing remains to be reordered. Now there are many sorting algorithms, but they all do this, in different ways. So then how are elements reordered? By comparing two given elements, and deciding which comes first, and swapping them if needed.
We can separate the overall reordering and swapping parts from the comparison part, and write a sort function that will take care of all the repeated reordering stuff, and just require the caller to specify how to compare two elements. If the list consists of numbers, it's almost always the case that the way to compare them is to just take their value. But suppose the list consists of things a little more complicated, like cars. How do you compare two cars? Well, you could compare them by numerically comparing their top speed. Or their gas mileage. Or price.
But the comparison doesn't have to be numerical. We could compare two cars by actually racing them. We could compare two cars by just saying if one is blue and the other isn't, the blue one is ordered first, and if neither or both are blue they are ordered as they already are.
We could come up with all sorts of ways to compare two cars. And the sorting algorithm could then sort a list of cars, without knowing anything about cars, as long as we the caller just tell it how to compare cars - any two given cars. We just have to express that comparison as an expression that returns a boolean, where if it's true, the first car is ordered before the second one, and if it's false, the first car is ordered after the second one.
Returning to numbers, that's what sort { $0 > $1 } means, in Swift's very concise syntax: "Sort, where if the first element is > the second one, order the first one before the second one."
You asked how it can sort four numbers with only two indices. $0 and $1 are not bound to the four specific elements in the list [20, 19, 1, 12], they are bound to any two given numbers that need to be compared, because the sorting algorithm repeately needs to do this.
There are a few things to note. First, the operator > has to be defined for the kinds of elements you are sorting. In the example the elements are numbers, and > is indeed defined. Second, the sort function specifies that the boolean true orders the first one before the second rather than the other way around, so the comparison function follows that specification. Third, the last evaluated expression is taken as the boolean value to be used. Having these two assumptions beforehand allows the comparison function to be written so concisely.
So if we wanted to sort those cars by racing them, we could write it like this:
cars.sort {
winner_of_race_between($0, $1) == $0
// if the first car beats the second, it is sorted ahead
}
Or exclusive blueness:
cars.sort { //not guaranteed to be valid Swift, just consider this pseudocode
if(($0.color != Color.blue) && ($1.color == Color.blue) {
$1
} else if (($0.color == Color.blue) && ($1.color != Color.blue)) {
$0
} else { //leave them in same order
$0
}
}
extension Array {
public func mySorted(by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows -> [Element] {
var newArray: [Element] = self
if newArray.count <= 1 {
/// nothing to do
} else if newArray.count <= 32 { /// 32 ?? 64
for l in 1..<count {
for r in (0..<l).reversed() {
if try areInIncreasingOrder(newArray[r + 1], newArray[r]) {
(newArray[r + 1], newArray[r]) = (newArray[r], newArray[r + 1])
} else {
break
}
}
}
} else {
/// others sort
}
return newArray
}
}
var array: [Int] = [4, 6, 8, 1, 3]
let a1 = array.sorted {
print("\($0) \($1)")
return $0 > $1
}
print("---------")
let a2 = array.mySorted {
print("\($0) \($1)")
return $0 > $1
}
print("==========")
let a1 = array.sorted {
print("\($0) \($1)")
return $0 < $1
}
print("+++++++")
let a2 = array.mySorted {
print("\($0) \($1)")
return $0 < $1
}

Filter by date anjularjs

I am trying to filter by Date. The answer on this post worked for me by boindiil
AngularJS ngTable filtering by Date
The only problem I am having is that the filter for the Date is Case sensitive. How do I make it not to be case sensitive? When you run his code and you type lowercase j or f for the date, no results are shown. You have to type exactly what it is.
The Name filter is not case sensitive. you can type lowercase or uppercase it works.
You just need to add a check in your filter for lowercase as well.
Just replace
if($filter('date')(value.Date).indexOf(dateString) >= 0) {
filtered.push(value);
}
with
var lower = $filter('date')(value.Date.toDateString().toLowerCase()).indexOf(dateString);
var normal = $filter('date')(value.Date).indexOf(dateString);
if(normal >= 0 || lower >= 0) {
filtered.push(value);
}

Swift range bug with switch-statement

Hello guys I'm new here and right now I'm learning Swift by coding some fancy algorithms, which comes to my mind while reading Apples Swift book.
I was trying to compress (automatically downcast) any IntegerType value.
Here is a little snippet of my Code which almost works fine except for one case:
switch signedValue
{
case Int64(Int8.min)...Int64(Int8.max): compressedValue = Int8(signedValue)
case (Int64(Int8.max) + 1)...Int64(UInt8.max): compressedValue = UInt8(signedValue)
case Int64(Int16.min)...Int64(Int16.max): compressedValue = Int16(signedValue)
case (Int64(Int16.max) + 1)...Int64(UInt16.max): compressedValue = UInt16(signedValue)
case Int64(Int32.min)...Int64(Int32.max): compressedValue = Int32(signedValue)
case (Int64(Int32.max) + 1)...Int64(UInt32.max): compressedValue = UInt32(signedValue)
case Int64(Int.min)...Int64(Int.max): compressedValue = Int(signedValue) // range bug #1 - workaround '..<'
default: compressedValue = signedValue
}
Assume signedValue is of Type Int64 and the input value is = 10_000_000_000.
This will lead to a runtime error (in Playground):
Execution was interrupted, reason: EXC_BAD_INSTRUCTION ...
Could anyone help me out to understand what exactly is happening here. There is an workaround for this problem. Instead of '...' I could use '..<' but this not how the range should be.
Unlike intervals (which have two flavours, half-open or closed), Range is only ever half-open. So when you write 1...5, the ...function increments the right-hand argument in order to create a half-open range 1..<6.
The consequence of this is you can’t have a range that spans the entire length of an integer type, since 1...Int.max will result in an attempt to increment Int.max, and an overflow error. You get a similar error with let s = "hello"; let r = s.startIndex...s.endIndex
All is not lost, however, since you shouldn’t be using ranges anyway, this is a job for ClosedInterval. Since the ... operator is used for both, and defaults to ranges (for overloading precedence reasons) you need to explicitly identify the type:
let i64interval: ClosedInterval = Int64(Int64.min)...Int64(Int64.max)
switch signedValue {
// etc
case i64interval: compressedValue = Int(signedValue)
default: compressedValue = signedValue
}
Look at the documentation for the Range Type. It has the following little nugget of information that I never noticed before:
if T has a maximal value, it can serve as an endIndex, but can never be contained in a Range.
T, in that quote, is the type of value in the Range. So if you have a Range of Ints, the max value of the Int cannot be contained in the Range.
That's why it works if you put the ..< in there, instead of ....
Good question, by the way...