(Swift 3)
Kiểm tra xem một phần tử có tồn tại trong một mảng không (đáp ứng một số tiêu chí) và nếu có, hãy tiếp tục làm việc với phần tử đầu tiên như vậy
Nếu ý định là:
- Để kiểm tra xem một phần tử có tồn tại trong một mảng hay không (/ đáp ứng một số tiêu chí boolean, không nhất thiết phải kiểm tra tính bằng),
- Và nếu vậy, hãy tiếp tục và làm việc với phần tử đầu tiên như vậy,
Sau đó, một thay thế cho contains(_:)
như blueprinted Sequence
là first(where:)
của Sequence
:
let elements = [1, 2, 3, 4, 5]
if let firstSuchElement = elements.first(where: { $0 == 4 }) {
print(firstSuchElement) // 4
// ...
}
Trong ví dụ giả định này, việc sử dụng nó có vẻ ngớ ngẩn, nhưng sẽ rất hữu ích nếu truy vấn các mảng của các loại phần tử không cơ bản để tồn tại bất kỳ phần tử nào đáp ứng một số điều kiện. Ví dụ
struct Person {
let age: Int
let name: String
init(_ age: Int, _ name: String) {
self.age = age
self.name = name
}
}
let persons = [Person(17, "Fred"), Person(16, "Susan"),
Person(19, "Hannah"), Person(18, "Sarah"),
Person(23, "Sam"), Person(18, "Jane")]
if let eligableDriver = persons.first(where: { $0.age >= 18 }) {
print("\(eligableDriver.name) can possibly drive the rental car in Sweden.")
// ...
} // Hannah can possibly drive the rental car in Sweden.
let daniel = Person(18, "Daniel")
if let sameAgeAsDaniel = persons.first(where: { $0.age == daniel.age }) {
print("\(sameAgeAsDaniel.name) is the same age as \(daniel.name).")
// ...
} // Sarah is the same age as Daniel.
Bất kỳ hoạt động xích sử dụng .filter { ... some condition }.first
có thể được thay thế bằng first(where:)
. Cái sau cho thấy ý định tốt hơn và có lợi thế về hiệu suất so với các thiết bị không lười biếng có thể .filter
, vì những thứ này sẽ vượt qua toàn bộ mảng trước khi trích xuất phần tử đầu tiên (có thể) đi qua bộ lọc.
Kiểm tra xem một phần tử có tồn tại trong một mảng không (đáp ứng một số tiêu chí) và nếu có, hãy loại bỏ phần tử đầu tiên như vậy
Một bình luận bên dưới các truy vấn:
Làm thế nào tôi có thể loại bỏ firstSuchElement
khỏi mảng?
Một trường hợp sử dụng tương tự như trường hợp trên là loại bỏ phần tử đầu tiên đáp ứng một vị từ đã cho. Để làm như vậy, index(where:)
phương thức Collection
(có sẵn để thu thập mảng) có thể được sử dụng để tìm chỉ mục của phần tử đầu tiên đáp ứng vị từ, sau đó chỉ mục có thể được sử dụng với remove(at:)
phương thức Array
(có thể; nếu nó tồn tại) loại bỏ yếu tố đó
var elements = ["a", "b", "c", "d", "e", "a", "b", "c"]
if let indexOfFirstSuchElement = elements.index(where: { $0 == "c" }) {
elements.remove(at: indexOfFirstSuchElement)
print(elements) // ["a", "b", "d", "e", "a", "b", "c"]
}
Hoặc, nếu bạn muốn xóa phần tử khỏi mảng và làm việc với , hãy áp dụng phương thức Optional
: s map(_:)
cho điều kiện (để .some(...)
trả về từ index(where:)
) sử dụng kết quả từ index(where:)
để loại bỏ và bắt phần tử bị xóa khỏi mảng (trong mệnh đề ràng buộc tùy chọn) .
var elements = ["a", "b", "c", "d", "e", "a", "b", "c"]
if let firstSuchElement = elements.index(where: { $0 == "c" })
.map({ elements.remove(at: $0) }) {
// if we enter here, the first such element have now been
// remove from the array
print(elements) // ["a", "b", "d", "e", "a", "b", "c"]
// and we may work with it
print(firstSuchElement) // c
}
Lưu ý rằng trong ví dụ được nêu ở trên, các thành viên mảng là các loại giá trị đơn giản ( String
ví dụ), do đó, việc sử dụng một vị từ để tìm một thành viên nhất định là hơi quá, vì chúng ta có thể kiểm tra sự bằng nhau bằng cách sử dụng index(of:)
phương pháp đơn giản hơn như trong câu trả lời của @ DogCoffee . Nếu áp dụng phương pháp tìm và loại bỏ ở trên choPerson
Tuy nhiên, ví dụ, sử dụng index(where:)
với một vị từ là phù hợp (vì chúng ta không còn kiểm tra tính bằng mà để hoàn thành một vị từ được cung cấp).
if find(elements, 5) != nil { }
không đủ tốt