Сравнение массивов с -nan - PullRequest
0 голосов
/ 28 января 2019

У меня есть два двойных массива с равным количеством элементов.Оба они содержат числа и некоторые значения NaN после тригонометрических вычислений.

Мне нужно сравнить каждый элемент первого массива с каждым элементом второго, найти большее число и поместить его в новый третий массив.В конце третий массив должен содержать то же количество элементов, что и первый или второй массив.

Если сравниваются две Nan, мне нужно отобразить конкретное сообщение об ошибке «Страшная ошибка» по этому точному индексу.Поэтому я думаю, что третий массив должен быть String, чтобы иметь возможность отображать как числа, так и сообщения об ошибках.Если двойное число сравнивается с NaN, двойное число всегда следует выбирать как большее.

Как мне все это сделать?

Вот мой код:

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
}

1 Ответ

0 голосов
/ 28 января 2019

Вы можете использовать zip для одновременной итерации по двум массивам, а затем 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)
...