arrays - que - saber si un elemento existe en un array javascript
Cómo comprobar si un elemento está en una matriz (14)
¿Qué hay de usar una tabla hash para el trabajo, como este?
Primero, creando una función genérica de "mapa hash", extendiendo el protocolo de secuencia.
extension Sequence where Element: Hashable {
func hashMap() -> [Element: Int] {
var dict: [Element: Int] = [:]
for (i, value) in self.enumerated() {
dict[value] = i
}
return dict
}
}
Esta extensión funcionará siempre que los elementos de la matriz se ajusten a Hashable, como enteros o cadenas, aquí está el uso ...
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
Pero por ahora, concentrémonos en comprobar si el elemento está en la matriz.
let numExists = indexOfnumToDetect != nil // if the key does not exist
means the number is not contained in the collection.
print(numExists) // prints true
En Swift, ¿cómo puedo verificar si un elemento existe en una matriz? Xcode no tiene ninguna sugerencia para contain
, include
o has
, y una búsqueda rápida a través del libro resultó nada. ¿Alguna idea de cómo comprobar esto? Sé que hay un método de find
que devuelve el número de índice, pero ¿hay un método que devuelva un booleano como ruby #include?
?
Ejemplo de lo que necesito:
var elements = [1,2,3,4,5]
if elements.contains(5) {
//do something
}
A partir de Swift 2.1, los NSArrays han containsObject
que se pueden usar así:
if myArray.containsObject(objectImCheckingFor){
//myArray has the objectImCheckingFor
}
Aquí está mi pequeña extensión que acabo de escribir para comprobar si mi matriz de delegados contiene un objeto delegado o no ( Swift 2 ). :) También funciona con tipos de valor como un encanto.
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
}
}
Si tiene una idea de cómo optimizar este código, hágamelo saber.
En caso de que alguien esté tratando de encontrar si una indexPath
está entre las seleccionadas (como en las UICollectionView
o UITableView
cellForItemAtIndexPath
):
var isSelectedItem = false
if let selectedIndexPaths = collectionView.indexPathsForSelectedItems() as? [NSIndexPath]{
if contains(selectedIndexPaths, indexPath) {
isSelectedItem = true
}
}
La forma más sencilla de lograr esto es usar el filtro en la matriz.
let result = elements.filter { $0==5 }
result
tendrá el elemento encontrado si existe y estará vacío si el elemento no existe. Entonces, simplemente verificar si el result
está vacío le dirá si el elemento existe en la matriz. Yo usaría lo siguiente:
if result.isEmpty {
// element does not exist in array
} else {
// element exists
}
Para aquellos que vinieron aquí en busca de encontrar y eliminar un objeto de una matriz:
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)
}
Rápido
Si no está utilizando el objeto, puede utilizar este código para los contenidos.
let elements = [ 10, 20, 30, 40, 50]
if elements.contains(50) {
print("true")
}
Si está utilizando NSObject Class en swift. Estas variables están de acuerdo con mi requerimiento. Usted puede modificar para su requerimiento.
var cliectScreenList = [ATModelLeadInfo]()
var cliectScreenSelectedObject: ATModelLeadInfo!
Esto es para un mismo tipo de datos.
{ $0.user_id == cliectScreenSelectedObject.user_id }
Si quieres cualquier tipo de objeto.
{ "/($0.user_id)" == "/(cliectScreenSelectedObject.user_id)" }
Estado completo
if cliectScreenSelected.contains( { $0.user_id == cliectScreenSelectedObject.user_id } ) == false {
cliectScreenSelected.append(cliectScreenSelectedObject)
print("Object Added")
} else {
print("Object already exists")
}
Si el usuario encuentra elementos de una matriz en particular, use el siguiente código igual que el valor entero.
var arrelemnts = ["sachin", "test", "test1", "test3"]
if arrelemnts.contains("test"){
print("found") }else{
print("not found") }
Si está verificando si una instancia de una clase o estructura personalizada está contenida en una matriz, deberá implementar el protocolo Equatable antes de poder usar .contains (myObject).
Por ejemplo:
struct Cup: Equatable {
let filled:Bool
}
static func ==(lhs:Cup, rhs:Cup) -> Bool { // Implement Equatable
return lhs.filled == rhs.filled
}
entonces puedes hacer
cupArray.contains(myCup)
Sugerencia : la anulación == debe ser a nivel global, no dentro de su clase / estructura
Swift 4, otra forma de lograr esto, con la función de filtro
elementos var = [1,2,3,4,5]
if let object = elements.filter({ $0 == 5 }).first {
print("found")
} else {
print("not found")
}
Utilicé filtro.
let results = elements.filter { el in el == 5 }
if results.count > 0 {
// any matching items are in results
} else {
// not found
}
Si quieres, puedes comprimir eso para
if elements.filter({ el in el == 5 }).count > 0 {
}
Espero que ayude.
Actualización para Swift 2
¡Hurra por implementaciones por defecto!
if elements.contains(5) {
// any matching items are in results
} else {
// not found
}
Utilice esta extensión:
extension Array {
func contains<T where T : Equatable>(obj: T) -> Bool {
return self.filter({$0 as? T == obj}).count > 0
}
}
Usar como:
array.contains(1)
Actualizado para Swift 2/3
Tenga en cuenta que a partir de Swift 3 (o incluso 2), la extensión ya no es necesaria, ya que la función global de contains
se ha convertido en un par de métodos de extensión en Array
, lo que le permite realizar una de las siguientes acciones:
let a = [ 1, 2, 3, 4 ]
a.contains(2) // => true, only usable if Element : Equatable
a.contains { $0 < 1 } // => false
(Swift 3)
Verifique si existe un elemento en una matriz (que cumpla con algunos criterios) y , de ser así, continúe trabajando con el primer elemento de este tipo.
Si la intención es:
- Para verificar si un elemento existe en una matriz (/ cumple con algunos criterios booleanos, no necesariamente pruebas de igualdad),
- Y si es así, proceda y trabaje con el primer elemento,
Entonces, una alternativa a los contains(_:)
como Sequence
planos es first(where:)
de la Sequence
:
let elements = [1, 2, 3, 4, 5]
if let firstSuchElement = elements.first(where: { $0 == 4 }) {
print(firstSuchElement) // 4
// ...
}
En este ejemplo artificial, su uso puede parecer tonto, pero es muy útil si se consultan matrices de tipos de elementos no fundamentales para ver si existen elementos que cumplan alguna condición. P.ej
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.
Cualquier operación encadenada que use .filter { ... some condition }.first
puede ser reemplazada favorablemente con la first(where:)
. Este último muestra mejor la intención y tiene ventajas de rendimiento sobre posibles dispositivos no perezosos de .filter
, ya que estos pasarán la matriz completa antes de extraer el primer elemento (posible) que pasa el filtro.
Verifique si existe un elemento en una matriz (que cumpla con algunos criterios) y , de ser así, elimine el primer elemento de este tipo.
Un comentario debajo de las consultas:
¿Cómo puedo eliminar el
firstSuchElement
de la matriz?
Un caso de uso similar al anterior es eliminar el primer elemento que cumple un determinado predicado. Para hacerlo, el index(where:)
método de Collection
(que está fácilmente disponible para la colección de matrices) se puede usar para encontrar el índice del primer elemento que cumple el predicado, después de lo cual el índice se puede usar con la remove(at:)
Método de Array
para (posible; dado que existe) eliminar ese elemento.
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"]
}
O, si desea eliminar el elemento de la matriz y trabajar con él , aplique Optional
: s map(_:)
método a condicionalmente (para .some(...)
retorno del index(where:)
) use el resultado desde el index(where:)
para eliminar y capturar el elemento eliminado de la matriz (dentro de una cláusula de enlace opcional).
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
}
Tenga en cuenta que en el ejemplo creado anteriormente, los miembros de la matriz son tipos de valor simples (instancias de String
), por lo que usar un predicado para encontrar un miembro determinado es un poco más de matanza, ya que podríamos simplemente probar la igualdad usando el método de index(of:)
como se muestra en la respuesta de @ DogCoffee . Sin embargo, si aplica el método de buscar y eliminar que aparece más arriba en el ejemplo de Person
, usar el index(where:)
con un predicado es apropiado (ya que no probamos la igualdad sino que cumplimos con un predicado suministrado).
Swift 2, 3, 4
let elements = [1, 2, 3, 4, 5]
if elements.contains(5) {
print("yes")
}
contains()
es un método de extensión de protocolo de SequenceType
(para secuencias de elementos Equatable
) y no un método global como en versiones anteriores.
Observaciones:
- Este método
contains()
requiere que los elementos de secuencia adopten el protocoloEquatable
, compare, por ejemplo, la respuesta de Andrews . - Si los elementos de la secuencia son instancias de una subclase
NSObject
entonces debe anularisEqual:
vea la subclase NSObject en Swift: hash vs hashValue, isEqual vs == . - Existe otro método
contains()
más general) quecontains()
que no requiere que los elementos sean comparables y toma un predicado como un argumento. Consulte, por ejemplo, ¿ Taquigrafía para probar si un objeto existe en una matriz para Swift? .
Swift versiones anteriores:
let elements = [1,2,3,4,5]
if contains(elements, 5) {
println("yes")
}