0

I am quite new to Swift 3 and to programming languages in general. I have the following arrays inside an array and a variable income:

let testArray: [[Double]] = [
    [0,0],
    [1000,20.5],
    [3000,21],
    [4000,22.5],
   ]

var income: Double = 3500

What I want to do is something similar to the VLOOKUP function in Excel: I want to find in the first column of the arrays (i.e. 0, 1000, 3000, 4000) a number which is equal or immediately smaller than my variable. In this case, as income = 3500, the program should return 3000. I tried using filter() but I don't know how to work with the arrays inside the array. Any help appreciated.

1
  • thanks for the help ! Commented Nov 21, 2016 at 18:00

2 Answers 2

2

You can proceed as follows.

Get the first column of the array:

let firstColumn = testArray.map { $0[0] }
print(firstColumn) // [0.0, 1000.0, 3000.0, 4000.0]

Restrict to those elements which are less than or equal to the given amount:

let filtered = firstColumn.filter { $0 <= income }
print(filtered) // [0.0, 1000.0, 3000.0]

Get the maximal element of the filtered array. If the elements are sorted in increasing order then you can use last instead of max():

let result = filtered.max()!
// Or: let result = filtered.last!
print(result) // 3000.0

Putting it all together:

let result = testArray.map { $0[0] }.filter { $0 <= income }.max()!
print(result) // 3000.0

A possible optimization is to combine map and filter into flatMap:

let result = testArray.flatMap { $0[0] <= income ? $0[0] : nil }.max()!
print(result) // 3000.0

This code assumes that there is at least one matching element, otherwise last! or max()! would crash. If that is not guaranteed:

if let result = testArray.flatMap( { $0[0] <= income ? $0[0] : nil }).max() {
    print(result) // 3000.0
} else {
    print("no result")
}

Or provide a default value (0.0 in this example):

let result = testArray.flatMap( { $0[0] <= income ? $0[0] : nil }).max() ?? 0.0
print(result) // 3000.0
Sign up to request clarification or add additional context in comments.

3 Comments

Your answer is just better than mine :)
@NikolaiRuhe: I wouldn't say so. Your solution is straight-forward and avoids the creation of any intermediate arrays. It is worth to be preserved in my opinion.
The OP already tried to use filter and you're showing how that's done. Also, you avoid the sorting aspect elegantly. Questions in this level are more about teaching than providing a reference. I think my answer just distracts from that.
0

Something like this:

let testArray: [[Double]] = [
        [0,0],
        [1000,20.5],
        [3000,21],
        [3500,22.5],
        [3300,21],
]

let income: Double = 3500

var closest = testArray[0][0]
var closestDif = closest - income

for innerArray in testArray {
    let value = innerArray[0]

    let thisDif = value - income

    guard thisDif <= 0 else {
        continue
    }

    if closestDif < thisDif {
        closestDif = thisDif
        closest = value

        guard closestDif != 0 else {
            break
        }
    }
}

print(closest)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.