Reputation: 2356
extension Array where Element: Numeric {
func closest(to givenValue: Element) -> Element {
let sorted = self.sorted(by: <)
let over = sorted.first(where: { $0 >= givenValue })!
let under = sorted.last(where: { $0 <= givenValue })!
let diffOver = over - givenValue
let diffUnder = givenValue - under
return (diffOver < diffUnder) ? over : under
}
}
In line 3 of this example code, Xcode gives me the incomprehensible error message Ambiguous reference to member '<'
, along with this great list:
What am I supposed to do here? I just want this array to get sorted.
Upvotes: 2
Views: 405
Reputation: 1137
I was just running into a similar problem stemming from the type inference when chaining multiple higher order functions (sort, map, etc), when I found this post and I couldn't help but notice the inefficiency of your function.
Here is an example of how you can implement this same function using binary search, massively reducing the time it takes to execute on large datasets:
extension Array where Element: Numeric & Comparable {
func closest2(to target: Element) -> Element {
if target <= self[0] {
return self[0]
}
if target >= self[count - 1] {
return self[count - 1]
}
var i = 0
var j = count
var mid = 0
while i < j {
mid = (i + j) / 2
if self[mid] == target {
return self[mid]
}
if target < self[mid] {
if mid > 0 && target > self[mid - 1] {
return getClosest(val1: self[mid - 1], val2: self[mid], target: target)
}
j = mid
} else {
if mid < count - 1 && target < self[mid + 1] {
return getClosest(val1: self[mid], val2: self[mid + 1], target: target)
}
i = mid + 1
}
}
return self[mid]
}
private func getClosest(val1: Element, val2: Element, target: Element) -> Element {
return target - val1 > val2 - target ? val2 : val1
}
}
Upvotes: 0
Reputation: 5689
Problem is that you have defined your Element
as Numeric only where >
will work with Comparable
.
Do it as:
extension Array where Element: Numeric, Element: Comparable {
func closest(to givenValue: Element) -> Element {
//... your code here ...
}
}
Upvotes: 1
Reputation: 42858
You have to declare Element
to be Comparable
:
extension Array where Element: Numeric & Comparable {
Upvotes: 7
Reputation: 135
In
let sorted = self.sorted(by: <)
you're not giving a boolean function for the function to use. Maybe try replacing it with :
let sorted = self.sorted(by: { $0 < $1 })
Upvotes: 2