Swift: Check which value in NSArray is closest to another given value
Save the minimumDifference
as a variable.
Then iterate the array. Each time compare the difference in the value from the array to the minimum difference.
If the new difference is smaller then swap out the minimu difference.
At the end of the array you will have the minimum difference.
This is the same as finding the highest value, smallest value, etc...
how to find/filter the array element with the smallest positive difference
In Swift 2 you can do it as a "one-liner" with functional-style
programming:
let numbers = [ 1, 3, 7, 11]
let x = 6
let closest = numbers.enumerate().minElement( { abs($0.1 - x) < abs($1.1 - x)} )!
print(closest.element) // 7 = the closest element
print(closest.index) // 2 = index of the closest element
enumerate()
iterates over all array elements together with the
corresponding index, and minElement()
returns the "smallest"(index, element)
pair with respect to the closure.
The closure compares the absolute values of the difference of
two elements to x
.
(It is assumed here that the array is not empty, so that minElement()
does not return nil
.)
Note that this is probably not the fastest solution for large arrays,
because the absolute differences are computed twice for (almost) all
array elements. But for small arrays this should not matter.
Swift 3:
let numbers = [ 1, 3, 7, 11]
let x = 6
let closest = numbers.enumerated().min( by: { abs($0.1 - x) < abs($1.1 - x) } )!
print(closest.element) // 7
print(closest.offset) // 2
The Swift 1.2 version can be found in the edit history.
Find closest item in array that matches criteria in Swift?
Optimised solution using higher order functions:
func closestMatch(values: [Int64], inputValue: Int64) -> Int64? {
return (values.reduce(values[0]) { abs($0-inputValue) < abs($1-inputValue) ? $0 : $1 })
}
Swift is advancing with every version to optimise the performance and efficiency. With higher order functions finding the closest match in an array of values is much easier with this implementation. Change the type of value as per your need.
Finding the nearest, lower number in a sorted NSArray
The method you are looking for is -[NSArray indexOfObject:inSortedRange:options:usingComparator:]
. It performs a binary search. With the options:NSBinarySearchingInsertionIndex
option, if the value isn't found exactly, it returns the index where the object would be inserted, which is the index of the least larger element, or the count of items in the array.
NSTimeInterval currentTime = ...;
NSUInteger index = [times indexOfObject:@(currentTime)
inSortedRange:NSMakeRange(0, times.count)
options:NSBinarySearchingInsertionIndex
usingComparator:^(id object0, id object1) {
NSTimeInterval time0 = [object0 doubleValue];
NSTimeInterval time1 = [object1 doubleValue];
if (time0 < time1) return NSOrderedAscending;
else if (time0 > time1) return NSOrderedDescending;
else return NSOrderedSame;
}];
// If currentTime was not found exactly, then index is the next larger element
// or array count..
if (index == times.count || [times[index] doubleValue] > currentTime) {
--index;
}
Check if the values in an array go below a specific value
If it is not an array with lots of data, I don't see the reason why wouldn't you do it like this:
for (NSNumber *number in myArray) {
if ([number floatValue] < 10.0) {
// alert user
}
}
How to check if an element is in an array
Swift 2, 3, 4, 5:
let elements = [1, 2, 3, 4, 5]
if elements.contains(5) {
print("yes")
}
contains()
is a protocol extension method of SequenceType
(for sequences of Equatable
elements) and not a global method as in
earlier releases.
Remarks:
- This
contains()
method requires that the sequence elements
adopt theEquatable
protocol, compare e.g. Andrews's answer. - If the sequence elements are instances of a
NSObject
subclass
then you have to overrideisEqual:
, see NSObject subclass in Swift: hash vs hashValue, isEqual vs ==. - There is another – more general –
contains()
method which does not require the elements to be equatable and takes a predicate as an
argument, see e.g. Shorthand to test if an object exists in an array for Swift?.
Swift older versions:
let elements = [1,2,3,4,5]
if contains(elements, 5) {
println("yes")
}
How to find out which CGRect is closest from array?
You'll need to figure out what Rob asked. One option is signed distance comparison.
Video: Deriving the SDF of a Box
If multiple rectangles contain the point, the "closest" one will be the one whose closest edge to the point is farthest away, i.e. where the point is "more contained".
rects.min { [point = SIMD2(point)] in point.getSignedDistance(to: $0) }
public extension CGRect {
var center: CGPoint { .init(x: midX, y: midY) }
}
public protocol CGFloat2 {
var x: CGFloat { get }
var y: CGFloat { get }
}
extension CGPoint: CGFloat2 { }
extension CGSize: CGFloat2 {
public var x: CGFloat { width }
public var y: CGFloat { height }
}
import simd
public extension SIMD2 where Scalar == CGFloat.NativeType {
init<Float2: CGFloat2>(_ float2: Float2) {
self.init(x: float2.x, y: float2.y)
}
init(x: CGFloat, y: CGFloat) {
self.init(x: x.native, y: y.native)
}
/// Distance to the closest point on the rectangle's boundary.
/// - Note: Negative if inside the rectangle.
func getSignedDistance(to rect: CGRect) -> Scalar {
let distances =
abs( self - Self(rect.center) )
- Self(rect.size) / 2
return
all(sign(distances) .> 0)
? length(distances)
: distances.max()
}
}
public extension Sequence {
func min<Comparable: Swift.Comparable>(
by getComparable: (Element) throws -> Comparable
) rethrows -> Element? {
try self.min {
try getComparable($0) < getComparable($1)
}
}
}
Swift: Checking JSON values stored in values of NSMutableArray
- Get the ID from the JSON entry in the question
Any reason you need to have the ID thing in Int
?
If no, keep your questionID
as a String.
let questionID = entry["id"] as! String
(If yes, you can do something like this, but I omit this case.)
let questionID = Int(entry["id"] as! String)!
(Assuming your "content.json" never contains unexpected values...)
- store that in an array called alreadyAsked
Declare an instance property as:
var alreadyAsked: Set<String> = []
And append the questionID
as :
alreadyAsked.insert(questionID)
(I hope you know where you need to put this line.)
- check if the question that is loaded has already been seen. If so, skip and choose another
You can check it here and there in your code, but one possible place is inside the LoadQuestion(_:)
method.
You may need to return a value which indicates that the question is already asked:
func loadQuestion(index : Int) -> Bool
(You'd better follow a simple naming guideline: Use upper camel case only for types. Which improves the readability of your code when shared. I mean "shared" includes posting a question in a Q&A site.)
And after you get that questionID
, check it:
if alreadyAsked.contains(questionID) {
return false //already asked, so not again
}
You need to put return true
at the end of loadQuestion(_:)
.
You may need to repeat until loadQuestion(_:)
returns true.
var randomNumber: Int
repeat {
randomNumber = Int(arc4random_uniform(UInt32(allEntries.count)))
} while !loadQuestion(randomNumber)
(This is not efficient, but practically ("seemingly" would fit better?) it works. And keeping your word "If so, skip and choose another")
- if all questions have been seen, display in console none left to view
Check it before entering the loop above:
if allEntries.count > alreadyAsked.count {
var randomNumber: Int
repeat {
randomNumber = Int(arc4random_uniform(UInt32(allEntries.count)))
} while !loadQuestion(randomNumber)
loadScore()
adjustInterface()
} else {
//display in console none left to view
//...
}
Your code has many parts which are unsafe or in a bad manner, and some of them may be critical. You may post another question if you cannot resolve it yourself.
Related Topics
How to Pass a Completion Block to Another Class in Swift
Swift 3/4 Dash to Camel Case (Snake to Camelcase)
Dictionary Becomes Nil When Trying to Pass Back Cllocation Object to iOS App Extension
Swift - Nsdate - Remove Part of Date
Argument of '#Selector' Does Not Refer to an '@Objc' Method (Swift 3)
How to Build a Recursive Function in Swift to Return a String
How to Upload Images from The Browser to Amazon S3 Using Vapor and Leaf
How to Programmatically Change The Xdr Display Reference Mode (Aka Preset) on Macos
Implementing Ignoredproperties() on Both a Object Subclass and Its Own Subclass
Swiftui Navigationview Not See Image
Ambiguous Use of Recover Error While Using Promisekit
How to Set Default Clouse Param in View Method
Bool.Hashvalue Valid to Convert to Int
Optional Protocol Requirements, I Can't Get It to Work
Saving And/Or Querying User Display Names in Firebase Using Caseinsensitive
What Is This Syntax: Func Funcname(Stuff1)(Stuff2)->Returntype {}