回答:
swiftはいくつかの点でオブジェクト指向(および配列はオブジェクトではなく構造体)よりも機能的であるため、関数「find」を使用して配列を操作します。これはオプションの値を返すため、nil値を処理する準備をしてください。
let arr:Array = ["a","b","c"]
find(arr, "c")! // 2
find(arr, "d") // nil
Swift 2.0の更新:
古いfind
関数はSwift 2.0ではサポートされなくなりました!
Swift 2.0では、(の実装)のArray
拡張で定義された関数を使用して、要素のインデックスを検索する機能が得られます。CollectionType
Array
let arr = ["a","b","c"]
let indexOfA = arr.indexOf("a") // 0
let indexOfB = arr.indexOf("b") // 1
let indexOfD = arr.indexOf("d") // nil
さらに、述語を満たす配列の最初の要素の検索は、の別の拡張によってサポートされていCollectionType
ます。
let arr2 = [1,2,3,4,5,6,7,8,9,10]
let indexOfFirstGreaterThanFive = arr2.indexOf({$0 > 5}) // 5
let indexOfFirstGreaterThanOneHundred = arr2.indexOf({$0 > 100}) // nil
これら2つの関数find
は、以前と同様にオプションの値を返すことに注意してください。
Swift 3.0の更新:
indexOfの構文が変更されていることに注意してください。Equatable
あなたに適合するアイテムのために使うことができます:
let indexOfA = arr.index(of: "a")
メソッドの詳細なドキュメントは、https://developer.apple.com/reference/swift/array/1689674-indexにあります。
準拠していない配列項目のEquatable
場合は、以下を使用する必要がありますindex(where:)
。
let index = cells.index(where: { (item) -> Bool in
item.foo == 42 // test if this is the item you're looking for
})
Swift 4.2の更新:
Swift 4.2では、index
は使用されなくなりましたが、明確化のためにに分離されfirstIndex
てlastIndex
います。したがって、アイテムの最初または最後のインデックスを探しているかどうかに応じて、
let arr = ["a","b","c","a"]
let indexOfA = arr.firstIndex(of: "a") // 0
let indexOfB = arr.lastIndex(of: "a") // 3
indexOf
参考:自分で定義した構造体の配列を使用している場合、構造体はEquatable
プロトコルに準拠している必要があります。
tl; dr:
クラスの場合、以下を探している可能性があります。
let index = someArray.firstIndex{$0 === someObject}
完全な答え:
参照型(class
)でID比較を実行する必要がある場合があることに言及する価値があると思います。この場合===
、述語クロージャーでID演算子を使用する必要があるだけです。
Swift 5、Swift 4.2:
let person1 = Person(name: "John")
let person2 = Person(name: "Sue")
let person3 = Person(name: "Maria")
let person4 = Person(name: "Loner")
let people = [person1, person2, person3]
let indexOfPerson1 = people.firstIndex{$0 === person1} // 0
let indexOfPerson2 = people.firstIndex{$0 === person2} // 1
let indexOfPerson3 = people.firstIndex{$0 === person3} // 2
let indexOfPerson4 = people.firstIndex{$0 === person4} // nil
上記の構文は末尾クロージャ構文を使用しており、以下と同等であることに注意してください。
let indexOfPerson1 = people.firstIndex(where: {$0 === person1})
Swift 4 / Swift 3-以前呼び出されていた関数 index
Swift 2-以前は呼び出されていた関数 indexOf
*該当すると便利に注意してくださいコメントによってpaulbaileyに関するclass
実装タイプのEquatable
あなたが使用して比較する必要があるかどうかを検討する必要がある、===
(恒等演算子)または==
(等号演算子を)。を使用して照合する場合==
は、他のユーザーが提案した方法を使用できます(people.firstIndex(of: person1)
)。
Person
実装する場合Equatable
、これは必要ありません。
Binary operator '===' cannot be applied to operands of type '_' and 'Post'
、Post
私の構造体...何か考えはありますか?
structs
(およびenums
)は参照型ではなく値型です。参照タイプ(などclass
)のみがID比較ロジック(===
)を持っています。何をどうするかについては、他の回答を確認してくださいstructs
(基本的に、単にを使用しarray.index(of: myStruct)
、タイプが()にmyStruct
準拠していることを確認します)。Equatable
==
あなたはfilter
クロージャーで配列することができます:
var myList = [1, 2, 3, 4]
var filtered = myList.filter { $0 == 3 } // <= returns [3]
そして、あなたは配列を数えることができます:
filtered.count // <= returns 1
したがって、これらを組み合わせることで、配列に要素が含まれているかどうかを判断できます。
myList.filter { $0 == 3 }.count > 0 // <= returns true if the array includes 3
あなたがポジションを見つけたいのであれば、私は空想的な方法を見ていませんが、あなたは確かにこのようにそれを行うことができます:
var found: Int? // <= will hold the index if it was found, or else will be nil
for i in (0..x.count) {
if x[i] == 3 {
found = i
}
}
編集
その間、楽しいエクササイズのArray
ために、find
メソッドを持つように拡張しましょう:
extension Array {
func find(includedElement: T -> Bool) -> Int? {
for (idx, element) in enumerate(self) {
if includedElement(element) {
return idx
}
}
return nil
}
}
これでこれを行うことができます:
myList.find { $0 == 3 }
// returns the index position of 3 or nil if not found
Array
するfind
メソッドを持つようにビルトインを拡張する別の例を追加しました。これが良い習慣かどうかはまだわかりませんが、きちんとした実験です。
enumerate
ように改訂していたので、もう適用されませんが、あなたは完全に正しいです。
indexOf()
完璧に機能する一方で、それは唯一のインデックスを返します。
ある条件を満たす要素のインデックスの配列を取得するエレガントな方法を探していました。
以下にその方法を示します。
スウィフト3:
let array = ["apple", "dog", "log"]
let indexes = array.enumerated().filter {
$0.element.contains("og")
}.map{$0.offset}
print(indexes)
スウィフト2:
let array = ["apple", "dog", "log"]
let indexes = array.enumerate().filter {
$0.element.containsString("og")
}.map{$0.index}
print(indexes)
カスタムクラスの場合、Equatableプロトコルを実装する必要があります。
import Foundation
func ==(l: MyClass, r: MyClass) -> Bool {
return l.id == r.id
}
class MyClass: Equtable {
init(id: String) {
self.msgID = id
}
let msgID: String
}
let item = MyClass(3)
let itemList = [MyClass(1), MyClass(2), item]
let idx = itemList.indexOf(item)
printl(idx)
Swift 2の更新:
sequence.contains(element):指定されたシーケンス(配列など)に指定されたエレメントが含まれている場合にtrueを返します。
スウィフト1:
要素が配列内に含まれているかどうかを確認するだけの場合、つまりブールインジケーターを取得するだけの場合contains(sequence, element)
は、find(array, element)
次の代わりに使用します。
contains(sequence、element):指定されたシーケンス(配列など)に指定された要素が含まれている場合にtrueを返します。
以下の例をご覧ください。
var languages = ["Swift", "Objective-C"]
contains(languages, "Swift") == true
contains(languages, "Java") == false
contains([29, 85, 42, 96, 75], 42) == true
if (contains(languages, "Swift")) {
// Use contains in these cases, instead of find.
}
Swift 4.配列に[String:AnyObject]タイプの要素が含まれている場合。要素のインデックスを見つけるには、以下のコードを使用します
var array = [[String: AnyObject]]()// Save your data in array
let objectAtZero = array[0] // get first object
let index = (self.array as NSArray).index(of: objectAtZero)
または、辞書のキーに基づいてインデックスを検索する場合。ここで、配列にはモデルクラスのオブジェクトが含まれており、idプロパティと一致しています。
let userId = 20
if let index = array.index(where: { (dict) -> Bool in
return dict.id == userId // Will found index of matched id
}) {
print("Index found")
}
OR
let storeId = Int(surveyCurrent.store_id) // Accessing model key value
indexArrUpTo = self.arrEarnUpTo.index { Int($0.store_id) == storeId }! // Array contains models and finding specific one
Swift 2.1
var array = ["0","1","2","3"]
if let index = array.indexOf("1") {
array.removeAtIndex(index)
}
print(array) // ["0","2","3"]
スウィフト3
var array = ["0","1","2","3"]
if let index = array.index(of: "1") {
array.remove(at: index)
}
array.remove(at: 1)
let array
ますか?の使用にself
も疑問があります。
でスウィフト4あなたがたDataModelの列を横断している場合は、この方法をRHS = LHSを実装し、Equatable議定書に必ずデータモデルの適合を行い、その後にのみ、あなたは「の(.INDEX」を使用することができます。たとえば、
class Photo : Equatable{
var imageURL: URL?
init(imageURL: URL){
self.imageURL = imageURL
}
static func == (lhs: Photo, rhs: Photo) -> Bool{
return lhs.imageURL == rhs.imageURL
}
}
その後、
let index = self.photos.index(of: aPhoto)
Swift 2(Xcode 7を使用)にArray
はindexOf
、CollectionType
プロトコルによって提供されるメソッドが含まれています。(実際には、2つのindexOf
方法-引数を一致させるために等式を使用する方法と、クロージャを使用します。)
Swift 2以前は、コレクションなどのジェネリック型がそれらから派生した具象型(配列など)のメソッドを提供する方法はありませんでした。したがって、Swift 1.xでは「index of」はグローバル関数です...そして、名前も変更されたため、Swift 1.xではそのグローバル関数が呼び出されfind
ます。
... のindexOfObject
メソッドNSArray
や、Swift標準ライブラリに同等のものを持たないFoundationのその他のより洗練された検索メソッドを使用することも可能です(ただし必須ではありません)。ただimport Foundation
(またはFoundationを推移的にインポートする別のモジュール)、をにキャストするArray
とNSArray
、で多くの検索メソッドを使用できますNSArray
。
この解決策はどれも私にとってはうまくいきます
これは私がSwift 4のために持っている解決策です:
let monday = Day(name: "M")
let tuesday = Day(name: "T")
let friday = Day(name: "F")
let days = [monday, tuesday, friday]
let index = days.index(where: {
//important to test with === to be sure it's the same object reference
$0 === tuesday
})
関数型ライブラリDollarを使用して、配列に対してindexOfを実行することもできます。たとえば、http://www.dollarswift.org/#indexof-indexof
$.indexOf([1, 2, 3, 1, 2, 3], value: 2)
=> 1
まだSwift 1.xで作業している場合
その後、
let testArray = ["A","B","C"]
let indexOfA = find(testArray, "A")
let indexOfB = find(testArray, "B")
let indexOfC = find(testArray, "C")
SWIFT 4
cardButtonsという配列の数値をcardNumberに格納するとします。次のようにできます。
let cardNumber = cardButtons.index(of: sender)
送信者はボタンの名前です
誰かがこの問題を抱えている場合
Cannot invoke initializer for type 'Int' with an argument list of type '(Array<Element>.Index?)'
これを行う
extension Int {
var toInt: Int {
return self
}
}
その後
guard let finalIndex = index?.toInt else {
return false
}
ために (>= swift 4.0)
かなりシンプルです。次のArray
オブジェクトを考えます。
var names: [String] = ["jack", "rose", "jill"]
要素のインデックスを取得するために必要なことは、次のrose
とおりです。
names.index(of: "rose") // returns 1
注意:
Array.index(of:)
を返しますOptional<Int>
。
nil
要素が配列に存在しないことを意味します。
戻り値を強制的にアンラップするかif-let
、オプションを回避するためにを使用することができます。