Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift Reducing an array of Tuples in

Tags:

swift

Is there a way in which I can call the reduce function on an array of tuples to find a max value?

For example

struct Gate{

    var maxedOpenGates = 1

    var GatesOpen : [(openOrdered : Int, gateNum : Int )] = []

    init(defaultSelected : Int = 0){

        GatesOpen.append(openOrdered : 1, gateNum : defaultSelected)
    }

    private func manipulateGates(gates : [SegmentButton]){
        for i in GatesOpen{
            gates[i.gateNum].toggleSelected()
        }

    }

    mutating func openGate(index : Int, buttons : [SegmentButton]){

        if GatesOpen.count < maxedOpenGates{
            GatesOpen.append(  openOrdered: GatesOpen.count , gateNum: index)

        }else{
         //////Finding the gate that was Opened the longest////
            let lastGate = GatesOpen.reduce(Int.min,{ max($0,$1) })

        }
        manipulateGates(buttons)
    }
}

where a I am trying to reduce based on openOrdered

 let lastGate = GatesOpen.reduce(Int.min,{ max($0,$1) })
like image 206
MooCow Avatar asked Apr 22 '15 04:04

MooCow


2 Answers

Yes, you can reduce an array of tuples like any other array. The arguments of the combine function are elements of the array, in your case "gate tuples". And if the result of reducing the array should also be a gate tuple then the initial element and the result of the combine function must also be of that type:

let lastGate = gatesOpen.reduce(gatesOpen[0]) {
        $0.openOrdered < $1.openOrdered ? $1 : $0
}

Of course the array must have at least one element for this to work. To avoid the unnecessary comparison of gatesOpen[0] with itself you can change it to (edited after @Airspeed's comment):

let lastGate = dropFirst(gatesOpen).reduce(gatesOpen[0]) {
    $0.openOrdered < $1.openOrdered ? $1 : $0
}
like image 167
Martin R Avatar answered Sep 28 '22 01:09

Martin R


Using closure with reduce function,

 //////Finding the gate that was Opened the longest////
let intitalValue = (Int.min,Int.min)
let lastGate: (openOrdered: Int, gateNum: Int) = GatesOpen.reduce(intitalValue){
         (longestOpenGate: (openOrdered: Int, gateNum: Int), gate) in
          if(longestOpenGate.openOrdered < gate.openOrdered) {
                  return gate;
          } else {
                  return longestOpenGate;
          }

}
let lastGateNumber = lastGate.gateNum;

Or,

let lastGate: (openOrdered: Int, gateNum: Int) = GatesOpen.reduce(intitalValue){
   $0.openOrdered < $1.openOrdered ? $1 : $0
}
let lastGateNumber = lastGate.gateNum;
like image 26
bhavesh Avatar answered Sep 28 '22 01:09

bhavesh