Jak sprawdzić, czy element jest w tablicy
W języku Swift, Jak mogę sprawdzić, czy element istnieje w tablicy? Xcode nie posiada żadnych sugestii dotyczących contain
, include
, albo has
, A Szybkie przeszukanie książki nic nie dało. Jakiś pomysł, jak to sprawdzić? Wiem, że istnieje metoda find
, która zwraca numer indeksu, ale czy istnieje metoda, która zwraca wartość logiczną podobną do #include?
Rubiego?
Przykład tego, czego potrzebuję:
var elements = [1,2,3,4,5]
if elements.contains(5) {
//do something
}
14 answers
Swift 2, 3, 4:
let elements = [1, 2, 3, 4, 5]
if elements.contains(5) {
print("yes")
}
contains()
is a protocol extension method of SequenceType
(dla sekwencji Equatable
elementów), a nie metoda globalna jak w
wcześniejsze wydania.
uwagi:
- ta metoda
contains()
wymaga, aby elementy sekwencji przyjmij ProtokółEquatable
, porównaj np. odpowiedź Andrewsa . - Jeśli elementy sekwencji są instancjami
NSObject
podklasy następnie musisz nadpisaćisEqual:
, Zobacz podklasa NSObject w języku Swift: hash vs hashValue, isEqual vs ==. - istnieje inna-bardziej ogólna -
contains()
Metoda, która nie wymaga równania elementów i przyjmuje predykat jako argument, patrz np. skrót aby sprawdzić czy obiekt istnieje w tablicy dla Swift?.
Swift starsze wersje:
let elements = [1,2,3,4,5]
if contains(elements, 5) {
println("yes")
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-04 08:51:04
Dla tych, którzy przybyli tutaj szukając znalezienia i usunięcia obiektu z tablicy:
Swift 1
if let index = find(itemList, item) {
itemList.removeAtIndex(index)
}
Swift 2
if let index = itemList.indexOf(item) {
itemList.removeAtIndex(index)
}
Swift 3, 4
if let index = itemList.index(of: item) {
itemList.remove(at: index)
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-04 09:02:54
Użyj tego rozszerzenia:
extension Array {
func contains<T where T : Equatable>(obj: T) -> Bool {
return self.filter({$0 as? T == obj}).count > 0
}
}
Użyj jako:
array.contains(1)
Aktualizacja dla Swift 2/3
Zauważ, że od Swift 3 (lub nawet 2) rozszerzenie nie jest już konieczne, ponieważ funkcja global contains
została przekształcona w parę metod rozszerzenia na Array
, które pozwalają wykonać jedną z następujących czynności:
let a = [ 1, 2, 3, 4 ]
a.contains(2) // => true, only usable if Element : Equatable
a.contains { $0 < 1 } // => false
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-05 18:53:11
Jeśli sprawdzasz, czy instancja custom class lub struct jest zawarta w tablicy, musisz zaimplementować Equatable protokół zanim będzie można go użyć .zawiera(myObject).
Na przykład:
struct Cup: Equatable {
let filled:Bool
}
static func ==(lhs:Cup, rhs:Cup) -> Bool { // Implement Equatable
return lhs.filled == rhs.filled
}
Wtedy możesz zrobić:
cupArray.contains(myCup)
Wskazówka: nadpisanie = = powinno być na poziomie globalnym, a nie w twojej klasie / strukturze
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-12 18:11:45
Użyłem filtra.
let results = elements.filter { el in el == 5 }
if results.count > 0 {
// any matching items are in results
} else {
// not found
}
Jeśli chcesz, możesz to skompresować do
if elements.filter({ el in el == 5 }).count > 0 {
}
Mam nadzieję, że to pomoże.
Aktualizacja dla Swift 2
Hurra dla domyślnych implementacji!if elements.contains(5) {
// any matching items are in results
} else {
// not found
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-13 22:45:14
(Swift 3)
Sprawdź, czy element istnieje w tablicy (spełniającej pewne kryteria), i jeśli tak, kontynuuj pracę z pierwszym takim elementem
Jeśli intencja jest:
-
Aby sprawdzić, czy element istnieje w tablicy (/spełnia pewne kryteria logiczne, niekoniecznie testowanie równości),
A jeśli tak, kontynuuj i pracuj z pierwszym takim elementem,
Wtedy alternatywa dla contains(_:)
Jak to wygląda w przypadku Sequence
first(where:)
Z Sequence
:
let elements = [1, 2, 3, 4, 5]
if let firstSuchElement = elements.first(where: { $0 == 4 }) {
print(firstSuchElement) // 4
// ...
}
W tym wymyślonym przykładzie, jego użycie może wydawać się głupie, ale jest bardzo przydatne, gdy odpytywanie tablic o nie fundamentalne typy elementów o istnienie jakichkolwiek elementów spełniających jakiś warunek. Np.
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.
Dowolne operacje łańcuchowe przy użyciu .filter { ... some condition }.first
można zastąpić first(where:)
. Ta ostatnia pokazuje intencję lepiej i ma przewagę wydajności nad możliwymi nie leniwymi urządzeniami .filter
, ponieważ przejdą one pełną tablicę przed ekstrakcją (możliwe) pierwszy element przechodzący przez filtr.
Sprawdź, czy element istnieje w tablicy (spełniającej pewne kryteria), i jeśli tak, usuń pierwszy taki element
Komentarz poniżej zapytań:
Jak mogę usunąć
firstSuchElement
z tablicy?
Podobny przypadek użycia do powyższego to usunięcie pierwszego elementu spełniającego dany predykat. W tym celu index(where:)
metoda Collection
(czyli łatwo dostępne do zbioru tablic) mogą być użyte do znalezienia indeksu pierwszego elementu spełniającego predykat, gdzie indeks może być użyty z remove(at:)
metoda Array
to (possible; give that it exists) usuwa ten element.
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"]
}
Lub, jeśli chcesz usunąć element z tablicy i pracować z, zastosuj Optional
: s map(_:)
metoda warunkowo (dla .some(...)
return from index(where:)
) użyj wyniku z index(where:)
aby usunąć i przechwycić usunięto element z tablicy (w ramach opcjonalnej klauzuli wiążącej).
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
}
Zauważ, że w wymyślonym przykładzie powyżej członkowie tablicy są prostymi typami wartości( instancjeString
), więc użycie predykatu do znalezienia danego elementu jest nieco przesadne, ponieważ możemy po prostu przetestować równość za pomocą prostszej metody index(of:)
, Jak pokazano w @DogCoffee ' s answer. Jeśli jednak zastosowanie metody znajdź i usuń powyżej do przykładu Person
, użycie index(where:)
z predykatem jest właściwe (ponieważ nie testujemy już równości, ale spełniamy dostarczony predykat).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:35
Najprostszym sposobem na to jest użycie filtra na tablicy.
let result = elements.filter { $0==5 }
result
będzie miał znaleziony element, jeśli istnieje i będzie pusty, jeśli element nie istnieje. Tak więc proste sprawdzenie czy {[2] } jest puste powie Ci, czy element istnieje w tablicy. Użyłbym następującego:
if result.isEmpty {
// element does not exist in array
} else {
// element exists
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-01 15:45:37
Od Swift 2.1 NSArrays mają containsObject
, które mogą być używane tak:
if myArray.containsObject(objectImCheckingFor){
//myArray has the objectImCheckingFor
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-21 03:37:47
Na wszelki wypadek, gdyby ktoś próbował znaleźć, czy indexPath
jest wśród wybranych (jak w UICollectionView
lub UITableView
cellForItemAtIndexPath
Funkcje):
var isSelectedItem = false
if let selectedIndexPaths = collectionView.indexPathsForSelectedItems() as? [NSIndexPath]{
if contains(selectedIndexPaths, indexPath) {
isSelectedItem = true
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-08 15:43:27
Oto moje małe rozszerzenie, które napisałem, aby sprawdzić, czy moja tablica delegatów zawiera obiekt delegata, czy nie (Swift 2 ). :) Działa również z typami wartości jak urok.
extension Array
{
func containsObject(object: Any) -> Bool
{
if let anObject: AnyObject = object as? AnyObject
{
for obj in self
{
if let anObj: AnyObject = obj as? AnyObject
{
if anObj === anObject { return true }
}
}
}
return false
}
}
Jeśli masz pomysł jak zoptymalizować ten kod, daj mi znać.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-22 09:23:33
Swift
Jeśli nie używasz obiektu, możesz użyć tego kodu dla contains.
let elements = [ 10, 20, 30, 40, 50]
if elements.contains(50) {
print("true")
}
Jeśli używasz klasy NSObject w języku swift. Ta zmienna jest zgodna z moimi wymaganiami. możesz modyfikować do swoich wymagań.
var cliectScreenList = [ATModelLeadInfo]()
var cliectScreenSelectedObject: ATModelLeadInfo!
Jest to dla tego samego typu danych.
{ $0.user_id == cliectScreenSelectedObject.user_id }
Jeśli chcesz typu AnyObject.
{ "\($0.user_id)" == "\(cliectScreenSelectedObject.user_id)" }
Pełny stan
if cliectScreenSelected.contains( { $0.user_id == cliectScreenSelectedObject.user_id } ) == false {
cliectScreenSelected.append(cliectScreenSelectedObject)
print("Object Added")
} else {
print("Object already exists")
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-02 12:49:41
Jeśli użytkownik znajdzie określone elementy tablicy, użyj poniższego kodu tak samo jak wartość całkowita.
var arrelemnts = ["sachin", "test", "test1", "test3"]
if arrelemnts.contains("test"){
print("found") }else{
print("not found") }
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-03 06:51:56
Swift 4, inny sposób na osiągnięcie tego, z funkcją filtra
Var elements = [1,2,3,4,5]
if let object = elements.filter({ $0 == 5 }).first {
print("found")
} else {
print("not found")
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-08 13:10:49
A co z użyciem tabeli hash do pracy, jak to?
Po pierwsze, tworzenie funkcji generycznej "hash map", Rozszerzanie protokołu sekwencji.
extension Sequence where Element: Hashable {
func hashMap() -> [Element: Int] {
var dict: [Element: Int] = [:]
for (i, value) in self.enumerated() {
dict[value] = i
}
return dict
}
}
To rozszerzenie będzie działać tak długo, jak elementy w tablicy są zgodne z Hashable, jak liczby całkowite lub łańcuchy, tutaj jest użycie...
let numbers = Array(0...50)
let hashMappedNumbers = numbers.hashMap()
let numToDetect = 35
let indexOfnumToDetect = hashMappedNumbers[numToDetect] // returns the index of the item and if all the elements in the array are different, it will work to get the index of the object!
print(indexOfnumToDetect) // prints 35
Ale na razie skupmy się na sprawdzeniu, czy element jest w tablicy.
let numExists = indexOfnumToDetect != nil // if the key does not exist
means the number is not contained in the collection.
print(numExists) // prints true
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-12 03:52:49