How to find index of list item in Swift?
As swift is in some regards more functional than object-oriented (and Arrays are structs, not objects), use the function "find" to operate on the array, which returns an optional value, so be prepared to handle a nil value:
let arr:Array = ["a","b","c"]
find(arr, "c")! // 2
find(arr, "d") // nil
Use firstIndex
and lastIndex
- depending on whether you are looking for the first or last index of the item:
let arr = ["a","b","c","a"]
let indexOfA = arr.firstIndex(of: "a") // 0
let indexOfB = arr.lastIndex(of: "a") // 3
Swift arrays identity Type does not conform to protocol 'AnyObject' error
According to The Swift Programing Language:
”Identical to” [represented by three equals signs, or ===] means that two constants or variables of class type
refer to exactly the same class instance.
In Swift, Arrays are Structs. Therefore, you can't try to use ===
to compare one Array to another one. Otherwise, the following code - using NSArray - works fine and does not give any error message in Playground:
var a = [1, 2, 3] as NSArray //NSArray is not a Struct
var b = a
a === b //true
The explanation of this is given by The Swift Programing Language:
Structure instances are always passed by value, and class instances
are always passed by reference.
Of course, Identical to (===) has not the same goal than Equal to (==) which helps you to check that two instances are considered “equal” or “equivalent” in value. For example, the following code will compile in Playground without any error message:
var a = [1, 2, 3]
var b = a
a == b //true
How to get an object index from an array in swift
Read the error message carefully
...not contained in a closure
By definition a closure is enclosed in a pair of curly braces
array.indexOf({$0 == observer})
or with trailing closure syntax
array.indexOf{$0 == observer}
Edit:
Since a protocol does not conform to Equatable
by default use the identity operator
array.indexOf{$0 === observer}
Check if Swift array contains instance of object
Use the identity operator
static func ==(lhs: Car, rhs: Car) -> Bool {
return lhs === rhs
}
Or even without Equatable
myCars.contains{ $0 === mazda }
Edit: But a better solution is to implement equality rather than identity, for example a vendor
and type
property in the class
static func ==(lhs: Car, rhs: Car) -> Bool {
return lhs.vendor == rhs.vendor && lhs.type == rhs.type
}
Search for a value in two dimensional array
Here's a function which i implemented which checks if an element is listed within the multi-dimension array and returns the total elements found:
- using .flatMap(_:) to flattened the multi-dimension arrays into one level.
using .filter(_:) to return the elements that are allowed based on the predicate.
import UIKit
var groups = [[String]]()
// we create three simple string arrays for testing
var groupA = ["England", "Ireland", "Scotland", "Wales"]
var groupB = ["Canada", "Mexico", "United States"]
var groupC = ["China", "Japan", "South Korea"]
// then add them all to the "groups" array
groups.append(groupA)
groups.append(groupB)
groups.append(groupC)
func findElementInMultiDimension(element: String) -> Int {
var count = 0
let _ = groups.flatMap{$0.filter { (item) -> Bool in
if item.contains(element) {
count = count + 1
return true
} else {
return false
}
}}
return count
}
findElementInMultiDimension(element: "Mexico")
print(findElementInMultiDimension(element: "Mexico")) //prints 1
Hope this helps :)
How to get index of an item in a array?
As Oliver pointed out, you can use
let index = array.indexOf(myObject)
However, this will only work if your object conforms to the Equatable
protocol, to conform to it, you have to implement the ==
function, like this:
class MyClass {
}
extension MyClass: Equatable { }
func ==(lhs: MyClass, rhs: MyClass) -> Bool {
return lhs === rhs // === returns true when both references point to the same object
}
If your class inherits from NSObject
and your comparison is something other than just comparing pointers, you'll have to override isEqual:
as well
override func isEqual(object: AnyObject?) -> Bool {
guard let obj = object as? MyClass else { return false }
return self == obj
}
Find delegate in a swift Array of delegates
Update for Swift 4.2:
Assuming that the delegates are actually instances of a class, you could require that in the protocol by "inheriting" from "class":
protocol LocationManagerDelegate: class {
// ...
}
and then use the firstIndex(where:)
method, using the "identity operator===
:
class LocationManager: NSObject {
private var _delegates = [LocationManagerDelegate]()
func removeDelegate(delegate:LocationManagerDelegate) {
if let index = _delegates.firstIndex(where: { $0 === delegate }) {
_delegates.remove(at: index)
}
}
}
Old answer (Swift 1):
There are two slightly different contains()
functions:
func contains<S : SequenceType where S.Generator.Element : Equatable>(seq: S, x: S.Generator.Element) -> Bool
func contains<S : SequenceType, L : BooleanType>(seq: S, predicate: (S.Generator.Element) -> L) -> Bool
You are using the first one, which requires that the sequence elements conform to
the Equatable
protocol, i.e. they can be compared with ==
.
Assuming that the delegates are actually instances of a class, you could require
that in the protocol by "inheriting" from "class":
protocol LocationManagerDelegate : class {
// ...
}
and then use the second, predicate-based version of contains()
with the
identity operator ===
:
func removeDelegate(delegate:LocationManagerDelegate) {
if contains(_delegates, { $0 === delegate }) {
// Remove delegate
}
}
To remove the object from the array you'll have to get its index, so you might use
the findIdenticalObject()
function from https://stackoverflow.com/a/25543084/1187415:
func findIdenticalObject<T : AnyObject>(array: [T], value: T) -> Int? {
for (index, elem) in enumerate(array) {
if elem === value {
return index
}
}
return nil
}
and then find and remove from the array with
func removeDelegate(delegate:LocationManagerDelegate) {
if let index = findIdenticalObject(_delegates, delegate) {
_delegates.removeAtIndex(index)
}
}
Sort array from CoreData Identity
You have first to fetch the data then sort them
self.fetchData()
userArray.sort { $0.naamdeelnemer! < $1.naamdeelnemer!}
However this is not CoreData like. Fetch the data passing a sort descriptor. This is much more efficient
func fetchData() {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let request : NSFetchRequest<Punten> = Punten.fetchRequest()
request.sortDescriptors = [NSSortDescriptor(key: "naamdeelnemer", ascending: true)]
do {
userArray = try context.fetch(request)
}
catch {
print(error)
}
}
and
userArray.sort { $0.naamdeelnemer! < $1.naamdeelnemer!}
Identify Duplicates In Array
Based on your comment I have made a simple example with string arrays, which can easily be converted to your movie type:
let movies = ["Batman","Batman","Flash","Avengers"]
var movieCounts:[String:Int] = [:]
for movie in movies {
movieCounts[movie] = (movieCounts[movie] ?? 0) + 1
}
And you can test it like so:
for (key, value) in movieCounts {
print("\(key) has been selected \(value) time/s")
}
Related Topics
iOS 13, Custom Image, Title and Subtitle in the Presented Uiactivityviewcontroller
Get Color of Point in a Skscene Swift
Mpmusicplayercontroller Setqueuewithstoreids Playing Index
Problems Accessing Calendar Using Ekeventstore on Osx Sierra with Swift 3
How to Turn Off Color Literals in Xcode
Drawing Pixels on the Screen Using Coregraphics in Swift
How to Test Asynchronous Methods Swift
Could Not Find an Overload for '+' That Accepts the Supplied Arguments
Swiftui: Using View Modifiers Between Different iOS Versions Without #Available
How to Check Whether an Object Is Kind of a Dynamic Class Type in Swift
Properly Using Firebase Cloud Functions and Stripe
Using Custom Cifilter on Calayer Shows No Change to Calayer
In What Situation Would One Use Expectationfornotification in Swift Testing
How to Add Multiple Values for One Key in a Dictionary Using Swift
@Objc Redundancy When Having @Objcmembers Private Dynamic Var