BLACK FRIDAY SALE: Save big on all my Swift books and bundles! >>

SOLVED: Best way to compare values and choose the largest value

Forums > SwiftUI

Hi everyone.

I'm building an app that compares measured voltage values in a 3 phase electrical system. My goal is to be able to calculate the phase imbalance. I have three computed properties which each calculate the difference between phase pair A-B, B-C and A-C and return the value as a Double

Now my next step is to take each of the calculated values and compare them between each other and choose the biggest value from that.

What would be the best way to go about this?


You could put them in an array and use the max() function in a computed property.

Something like this:

var diff1: Double {
    //calculate the diff between A-B

var diff2: Double {
    //calculate the diff between B-C

var diff3: Double {
    //calculate the diff between A-C

var maxDiff: Double {
    [diff1, diff2, diff3].max() ?? 0.0


While returning the max difference is very useful (@rooster's response), I wondered if you actually needed to know which pair of wires produced the max difference. Also took a shot at showing how breaking your big problem into smaller, solveable problems might be a useful technique.

Please add a post and let us know what you learned.

// Paste into Playgrounds

// This struct defines a single wire's properties.
struct Wire {
    var label:       String // Usually A, B, or C
    var voltage:     Double // Somewhere around 220 v
    var description: String { "Wire \(label) carries \(voltage) volts."}

// This struct defines a pair of wires.
struct PhasePair: Comparable {
    // are two pairs the same?
    static func == (lhs: PhasePair, rhs: PhasePair) -> Bool {
        (lhs.leftWire.label == rhs.leftWire.label) && (rhs.leftWire.label == rhs.rightWire.label)
        // Note: Incomplete solution. 
        // You can argue Pair(A, B) is the same as Pair(B, A).
        // This is your homework assignment!

    // allows you to compare two phasePairs by voltage difference
    static func < (lhs: PhasePair, rhs: PhasePair) -> Bool {
        lhs.difference < rhs.difference // compare the volt differences between two pairs (A-B) < (B-C) ?

    let leftWire:   Wire  // one of the wires
    let rightWire:  Wire  // the other wire
    var pair:       String { "\(leftWire.label)-\(rightWire.label)"     }
    var difference: Double { abs(leftWire.voltage - rightWire.voltage)  } // absolute value

// This struct defines a three wire electrical system
struct ElectricalSystem {
    var aWire : Wire  // Your 3 phase system has three wires
    var bWire : Wire
    var cWire : Wire

    var pairOne:          PhasePair { PhasePair(leftWire: aWire, rightWire: bWire) }
    var pairTwo:          PhasePair { PhasePair(leftWire: aWire, rightWire: cWire) }
    var pairThree:        PhasePair { PhasePair(leftWire: bWire, rightWire: cWire) }
    var largestImbalance: PhasePair { [pairOne, pairTwo, pairThree].sorted()[2] } // Sort array. Grab last value.

// Test data for the Playground.
var aWire = Wire(label: "A", voltage: 224)
var bWire = Wire(label: "B", voltage: 234)
var cWire = Wire(label: "C", voltage: 225)
let ovenSupply = ElectricalSystem(aWire: aWire, bWire: bWire, cWire: cWire)
ovenSupply.largestImbalance.pair // return the string representation

print(aWire.description)  // print wire description
print("Wire pair " + ovenSupply.largestImbalance.pair + " has the largest imbalance. (\(ovenSupply.largestImbalance.difference) volts)")


A big thanks to both of you.

Obelix, I appreciate your reply, but to be honest it is a little bit too advanced for me at the moment so I could't quite figure it all out. I'll have to dig in more to the code you posted to try and understand it all...

I was able to solve that problem... only to find out that I'm facing a new one. :)

I now have a computed property that uses the biggest value and passes it onward into a another computed property that makes the imbalance calculation using all the values that are needed and that calculation is shown in a text view in the UI.

I have a problem regarding this text view. It says 'nan' before the user has entered values into the previous textfields. How can I make the text view show blank before the calculated values is passed on to be shown on that view?


Toni apologizes:

Obelix, I appreciate your reply, but to be honest it is a little bit too advanced
for me at the moment so I could't quite figure it all out.

Hey! No problem.

This is an example of taking a big engineering problem and breaking it down into smaller, solvable chunks. Sorry, if I pushed you into the deep end of the pool while you're still learning to swim!

But when you have a moment to think about the problem, consider each part of your physical 3-phase schematic.

You have three wires? What are the properties of those wires? (Wire struct)

You need to calculate the voltage difference between two different wires? I created a PhasePair structure that requires two Wire objects. Then using this new PhasePair object, I can calculate the differences just between these two. I ask myself, if I have two Wires, what do I want to know about them? Answer: Voltage difference, and pair labels.

Anyway, you might see how I took a larger electrical problem and decomposed it into smaller and smaller parts. Each part is responsible for a subset of calculations.

Keep coding!


Toni found a bug!

I have a problem regarding this text view.
It says 'nan' before the user has entered values into the previous textfields.

nan is debugger speak for "Not a number"

This might be a great case for using an Optional. Optionals make programmer's head explode when they're first encountered in Swift lessons. But hear me out.

If you have values, you can perform a calculation.

But what if you don't have all the required values? What do you want your user to see?

In some cases, you might want to substitute a default input value, say zero. But what about the case where the input value IS zero? This is bad because now you don't know if there is no value, or the user actually wants zero.

In othercases, you might want to display nothing. You're the programmer. This is your decision to make.

You can use guard statements in your calculation to ensure that all the required values are within input specifications. But you need to plan out what the return result is if any value is missing or invalid.


Hacking with Swift is sponsored by RevenueCat

SPONSORED In-app subscriptions are a pain to implement, hard to test, and full of edge cases. RevenueCat makes it straightforward and reliable so you can get back to building your app. Oh, and it's free if your app makes less than $10k/mo.

Learn more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

Unknown user

You are not logged in

Log in or create account

Link copied to your pasteboard.