我有两个元素数量相等的Double数组。三角计算后,它们都包含数字和一些NaN值。
我需要将第一个数组的每个元素与第二个数组的每个元素进行比较,找到更大的数字,然后将其放入新的第三个数组中。最后,第三个数组应包含与第一个或第二个数组相同数量的元素。
如果比较两个Nan,我需要在该确切索引处显示特定的错误消息“可怕的错误”。所以我猜第三个数组应该是String,以便能够同时显示数字和错误消息。如果将Double数与NaN进行比较,则应始终选择Double数。
我该怎么做?
这是我的代码:
import Foundation
var initValue = Double()
var finalValue = Double()
var stepValue = Double()
while true {
print("Enter the starting number of the range")
if let number = readLine(), Double(number) != nil {
initValue = Double(number)!
break
} else {
print("Enter the correct number!")
}
}
while true {
print("Enter the end value of the range")
if let number = readLine(), Double(number) != nil, Double(number)! > initValue {
finalValue = Double(number)!
break
} else {
print("Enter the correct number, which is greater than starting number of the range!")
}
}
while true {
print("Enter delta")
if let number = readLine(), Double(number) != nil {
stepValue = Double(number)!
break
} else {
print("Enter the correct number!")
}
}
var trueArray = [Double]()
for number in stride(from: initValue, through: finalValue, by: stepValue) {
trueArray.append(number)
}
func calcLn () -> [Double] {
let calculatedArray = trueArray.map { log(1-46/sin($0)) }
return calculatedArray
}
func calcTan () -> [String] {
let calculatedArray = trueArray.map { (tan($0)/46) }
return calculatedArray
}
答案 0 :(得分:0)
您可以使用zip
并发地遍历2个数组,然后使用map
将元素对转换为输出,如您所愿。开启(ln.isNaN, tan.isNaN)
并用它来表示各种情况及其结果是有用的。
这是一个艰难的开始:
import Darwin
func promptForDouble(
initialMessage: String,
errorMessage: String,
acceptanceCriteria isAcceptable: (Double) -> Bool = { _ in true }
) -> Double {
print(initialMessage)
while true {
if let number = readLine().flatMap(Double.init), isAcceptable(number) {
return number
}
print(errorMessage)
}
}
let initValue = promptForDouble(
initialMessage: "Enter the starting number of the range",
errorMessage: "Enter the correct number!"
)
let finalValue = promptForDouble(
initialMessage: "Enter the end value of the range",
errorMessage: "Enter the correct number, which is greater than starting number of the range!",
acceptanceCriteria: { initValue < $0 }
)
let stepValue = promptForDouble(
initialMessage: "Enter delta",
errorMessage: "Enter the correct number!"
)
// TODO: give these functions better names!
func calcLn(_ input: [Double]) -> [Double] {
return input.map { log(1 - 46/sin($0)) }
}
func calcTan(_ input: [Double]) -> [Double] {
return input.map { tan($0) / 46 }
}
func mergeResults(lns: [Double], tans: [Double]) -> [Double?] {
return zip(lns, tans).map { ln, tan -> Double? in
switch (ln.isNaN, tan.isNaN) {
case ( true, true): return nil // Return nil to express error. Don't introduce Strings yet.
case (false, true): return ln
case ( true, false): return tan
case (false, false): return max(ln, tan)
}
}
}
func printResults(_ a1: [Double], _ a2: [Double], _ a3: [Double?]) {
for (a, (b, c)) in zip(a1, zip(a2, a3)) {
let resultString = c.map(String.init) ?? "terrible error" // Note: Strings are only introduced at the UI/presentation layer
print("ln: \(a),\ttan: \(b),\tresult: \(resultString)")
}
}
// TODO: give these arrays better names!
let inputs = Array(stride(from: initValue, through: finalValue, by: stepValue))
let array1 = calcLn(inputs)
let array2 = calcTan(inputs)
let array3 = mergeResults(lns: array1, tans: array2)
printResults(array1, array2, array3)