Проверка содержимого массива на значения, определенные как Any, но гарантированно одного типа.
Основываясь на этом моем вопросе (и принятом ответе), я хочу проверить наличие значения в массиве.
Значение хранится в переменной, определенной как тип Any
и массив определяется как [Any]
,
Фактические типы значения, хранящегося в переменной и элементах в массиве, определяются во время выполнения, но гарантированно удовлетворяют следующим условиям:
- Оба типа (переменные и элементы массива) совпадают, и
- Они либо один из
String
,Int
или жеBool
,
Пока что у меня работает этот код:
var isContained = false
if let intValue = anyValue as? Int {
isContained = arrayOfAny.contains({element in return ((element as? Int) == intValue)})
}
else if let stringValue = anyValue as? String {
isContained = arrayOfAny.contains({element in return ((element as? String) == stringValue)})
}
else if let boolValue = anyValue as? Bool {
isContained = arrayOfAny.contains({element in return ((element as? Bool) == boolValue)})
}
Тем не менее, есть много логического дублирования, и я хотел бы сделать его умнее, возможно, что-то вроде этого:
isContained = arrayOfAny.contains({element in
return ((element as? Equatable) == (anyValue as? Equatable))
})
... но ограничения на использование протокола Equatable
стоять на пути. Любой совет?
1 ответ
Теперь я вижу, что вы пытаетесь сделать. Вот пример того, как вы можете заставить его работать
let arrayOfAny:[AnyObject] = [1,7,9,true, "string"]
func getAny(value:AnyObject) -> [AnyObject]{
return self.arrayOfAny.filter ({$0 === value})
}
Вышеприведенная функция вернет массив совпадений, который в идеале должен быть единственным результатом или пустым массивом.
Пример:
self.getAny(1) // [1]
self.getAny(0) // []
Вы также можете изменить его, чтобы просто вернуть Bool
func getAny(value:AnyObject) -> Bool{
return self.arrayOfAny.filter ({$0 === value}).count > 0
}
Пример:
self.getAny(1) // true
self.getAny(0) // false
Редактировать:
Как отметил Мартин Р, это не всегда будет работать. К сожалению, я не полностью проверил это, прежде чем опубликовать этот ответ. Поработав с этим некоторое время, я придумал очень похожий подход, который есть у NicolasMiari:
let arrayOfAny:[AnyObject] = [1,Int.max,9,true, "string"]
func getAny(anyValue:AnyObject) -> [AnyObject]{
return self.arrayOfAny.filter ({
var exist:Bool
switch anyValue.self{
case is String: exist = $0 as? String == anyValue as? String
break
case is Int: exist = $0 as? Int == anyValue as? Int
break
case is Bool: exist = $0 as? Bool == anyValue as? Bool
break
default: exist = false
}
return exist
})
}
Недостатком этого подхода является то, что int 1
а также true
будет возвращено при звонке self.getAny(1)
результат будет [1,1]
как 1
а также true
может быть успешно приведен к обоим Int
а также Bool
и не так, как вероятно, намеревался просто вернуться [1]
, Другими словами, если у вас просто есть true
в вашем массиве, не имея Int 1
вы все равно получите положительный результат, как если бы он существовал в вашем массиве. То же самое работает и наоборот.