1

let array = [52, 5, 13, 126, 17]

I think what i have to do is I need to use filter on a collection then need to use filter 3 times in this case with 3 different conditions Filter will return an array so I have to use its count to store it in the tuple.

Raxs
  • 19
  • 3

1 Answers1

1

You can get The number of values in the original array matching a certain condition, with filter and count like this:

(Codes below written and tested in Swift 3.)

//The number of values in the original array in the range 0 ..< 50.
let theNumberValuesInRange1 = intArray.filter{0..<50 ~= $0}.count

You can do the same things 3 times and write something like this:

func getTheNumbersInRanges(_ intArray: [Int]) -> (Int, Int, Int) {
    let theNumberValuesInRange1 = intArray.filter{0..<50 ~= $0}.count
    let theNumberValuesInRange2 = intArray.filter{50..<100 ~= $0}.count
    let theNumberValuesInRange3 = intArray.filter{100 <= $0}.count
    return (theNumberValuesInRange1, theNumberValuesInRange2, theNumberValuesInRange3)
}
print(getTheNumbersInRanges([52, 5, 13, 126, 17])) //->(3, 1, 1)

But filter generates intermediate Array, so, it's not efficient especially for big Arrays.

You can use reduce, with which no intermediate Arrays are generated.

let theNumberRange1Way2 = intArray.reduce(0) {count, value in 0..<50 ~= value ? count + 1 : count}

Applying this way to tuple, you can write something like this:

func getTheNumbersInRangesWay2(_ intArray: [Int]) -> (Int, Int, Int) {
    return intArray.reduce((0, 0, 0)) {countTuple, value in
        switch value {
        case 0 ..< 50:
            return (countTuple.0 + 1, countTuple.1, countTuple.2)
        case 50 ..< 100:
            return (countTuple.0, countTuple.1 + 1, countTuple.2)
        case let v where 100 <= v:
            return (countTuple.0, countTuple.1, countTuple.2 + 1)
        default:
            return countTuple
        }
    }
}
print(getTheNumbersInRangesWay2([52, 5, 13, 126, 17])) //->(3, 1, 1)
OOPer
  • 47,149
  • 6
  • 107
  • 142