ฉันพยายามที่จะหาโดยการค้นหาitem index
list
ไม่มีใครรู้วิธีการทำเช่นนั้น?
ฉันเห็นมีlist.StartIndex
และlist.EndIndex
แต่ฉันต้องการบางสิ่งบางอย่างเช่นงูlist.index("text")
ใหญ่
ฉันพยายามที่จะหาโดยการค้นหาitem index
list
ไม่มีใครรู้วิธีการทำเช่นนั้น?
ฉันเห็นมีlist.StartIndex
และlist.EndIndex
แต่ฉันต้องการบางสิ่งบางอย่างเช่นงูlist.index("text")
ใหญ่
คำตอบ:
ในขณะที่สวิฟท์นั้นมีฟังก์ชั่นมากกว่าอ็อบเจกต์ที่มุ่งเน้น (และ Arrays เป็น structs ไม่ใช่อ็อบเจกต์) ให้ใช้ฟังก์ชั่น "ค้นหา" เพื่อใช้งานกับอาเรย์ซึ่งส่งคืนค่าตัวเลือก
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
โปรดทราบว่าทั้งสองฟังก์ชั่นจะคืนค่าทางเลือกดังที่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
) คุณอาจต้องการทำการเปรียบเทียบตัวตนซึ่งในกรณีนี้คุณเพียงแค่ต้องใช้===
ตัวดำเนินการประจำตัวในการปิดเพรดิเคต:
สวิฟท์ 5 สวิฟต์ 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
เป็น struct ของฉัน ... ความคิดใด ๆ ?
structs
(และenums
) เป็นประเภทค่าไม่ใช่ประเภทอ้างอิง ประเภทการอ้างอิงเท่านั้น (เช่นclass
) มีตรรกะการเปรียบเทียบเอกลักษณ์ ( ===
) ตรวจสอบคำตอบอื่น ๆ สำหรับสิ่งที่ต้องทำ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
ไม่ได้อีกต่อไป แต่คุณพูดถูก
func firstIndex(of element: Element) -> Int?
var alphabets = ["A", "B", "E", "D"]
example1
let index = alphabets.firstIndex(where: {$0 == "A"})
example2
if let i = alphabets.firstIndex(of: "E") {
alphabets[i] = "C" // i is the index
}
print(alphabets)
// Prints "["A", "B", "C", "D"]"
ในขณะที่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.contain (องค์ประกอบ) : คืนค่าจริงถ้าลำดับที่กำหนด (เช่นอาร์เรย์) มีองค์ประกอบที่ระบุ
สวิฟท์ 1:
หากคุณต้องการตรวจสอบว่ามีองค์ประกอบอยู่ในอาร์เรย์หรือไม่นั่นคือเพียงรับตัวบ่งชี้บูลีนใช้contains(sequence, element)
แทนfind(array, element)
:
บรรจุ (ลำดับองค์ประกอบ) : ผลตอบแทนจริงถ้าลำดับที่กำหนด (เช่นอาร์เรย์) มีองค์ประกอบที่ระบุ
ดูตัวอย่างด้านล่าง:
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.2
.index (โดยที่ :)ถูกเปลี่ยนเป็น. firstIndex (โดยที่ :)
array.firstIndex(where: {$0 == "person1"})
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)
หรือถ้าคุณต้องการที่จะพบดัชนีบนพื้นฐานของคีย์จากพจนานุกรม อาเรย์ที่นี่มี Objects of Model class และฉันกำลังจับคู่คุณสมบัติ 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
สวิฟท์ 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
เป็นที่น่าสงสัยด้วย
ในSwift 4หากคุณสำรวจผ่านอาเรย์ DataModel ของคุณตรวจสอบให้แน่ใจว่ารูปแบบข้อมูลของคุณเป็นไปตาม Equatable Protocol ใช้วิธีการ lhs = rhs และจากนั้นคุณสามารถใช้ ".index (of") เท่านั้น
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
โปรโตคอล (ที่จริงแล้วสองindexOf
วิธี - วิธีหนึ่งที่ใช้ความเท่าเทียมกันเพื่อจับคู่ข้อโต้แย้งและอีกวิธีหนึ่งที่ใช้การปิด)
ก่อนหน้า Swift 2 ไม่มีวิธีใดที่ประเภททั่วไปเช่นคอลเลกชันเพื่อให้วิธีการสำหรับประเภทคอนกรีตที่ได้มาจากพวกเขา (เช่นอาร์เรย์) ดังนั้นในสวิฟท์ 1.x "index of" เป็นฟังก์ชั่นระดับโลก ... และมันก็เปลี่ยนชื่ออีกด้วยดังนั้นในสวิฟท์ 1.x find
ว่าฟังก์ชั่นระดับโลกที่เรียกว่า
นอกจากนี้ยังเป็นไปได้ (แต่ไม่จำเป็น) เพื่อใช้indexOfObject
วิธีการจากNSArray
... หรือวิธีการอื่นที่ซับซ้อนกว่านี้จากมูลนิธิที่ไม่มีการเทียบเท่าในห้องสมุดมาตรฐานของ Swift เพียงแค่import 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
})
นอกจากนี้คุณยังสามารถใช้ห้องสมุดทำงานดอลลาร์เพื่อทำ 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 3 คุณสามารถใช้ฟังก์ชั่นที่เรียบง่าย
func find(objecToFind: String?) -> Int? {
for i in 0...arrayName.count {
if arrayName[i] == objectToFind {
return i
}
}
return nil
}
สิ่งนี้จะให้ตำแหน่งตัวเลขเพื่อให้คุณสามารถใช้เช่น
arrayName.remove(at: (find(objecToFind))!)
หวังว่าจะเป็นประโยชน์
SWIFT 4
สมมติว่าคุณต้องการเก็บหมายเลขจากอาร์เรย์ที่เรียกว่า cardButtons ลงใน cardNumber คุณสามารถทำได้ด้วยวิธีนี้:
let cardNumber = cardButtons.index(of: sender)
ผู้ส่งคือชื่อของปุ่มของคุณ
สวิฟต์ 4
สำหรับประเภทอ้างอิง:
extension Array where Array.Element: AnyObject {
func index(ofElement element: Element) -> Int? {
for (currentIndex, currentElement) in self.enumerated() {
if currentElement === element {
return currentIndex
}
}
return nil
}
}
ใน Swift 4/5 ให้ใช้ "firstIndex" เพื่อค้นหาดัชนี
let index = array.firstIndex{$0 == value}
ในกรณีที่ใครบางคนมีปัญหานี้
Cannot invoke initializer for type 'Int' with an argument list of type '(Array<Element>.Index?)'
jsut ทำสิ่งนี้
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
เพื่อหลีกเลี่ยงทางเลือก
เพียงใช้เมธอด firstIndex
array.firstIndex(where: { $0 == searchedItem })