Swift에는 Underscore.js의 _.findWhere 와 같은 것이 있습니까?
유형의 구조체 배열이 있고 배열에 속성이 같은 T구조체 객체가 포함되어 있는지 확인하고 싶습니다 .nameFoo
사용하려고 find()하고 filter()기본 유형, 예와하지만, 그들은 단지 일 String또는 Int. Equitable프로토콜 또는 이와 유사한 것을 준수하지 않는 경우 오류가 발생 합니다.
Swift에는 Underscore.js의 _.findWhere 와 같은 것이 있습니까?
유형의 구조체 배열이 있고 배열에 속성이 같은 T구조체 객체가 포함되어 있는지 확인하고 싶습니다 .nameFoo
사용하려고 find()하고 filter()기본 유형, 예와하지만, 그들은 단지 일 String또는 Int. Equitable프로토콜 또는 이와 유사한 것을 준수하지 않는 경우 오류가 발생 합니다.
답변:
FWIW, 사용자 정의 기능이나 확장 기능을 사용하지 않으려면 다음을 수행하십시오.
let array = [ .... ]
if let found = find(array.map({ $0.name }), "Foo") {
let obj = array[found]
}
name먼저 배열을 생성 한 다음 배열을 생성 find합니다.
거대한 배열이있는 경우 다음을 수행 할 수 있습니다.
if let found = find(lazy(array).map({ $0.name }), "Foo") {
let obj = array[found]
}
또는 아마도 :
if let found = find(lazy(array).map({ $0.name == "Foo" }), true) {
let obj = array[found]
}
스위프트 5
요소가 존재하는지 확인
if array.contains(where: {$0.name == "foo"}) {
// it exists, do something
} else {
//item could not be found
}
요소 가져 오기
if let foo = array.first(where: {$0.name == "foo"}) {
// do something with foo
} else {
// item could not be found
}
요소와 오프셋을 가져옵니다
if let foo = array.enumerated().first(where: {$0.element.name == "foo"}) {
// do something with foo.offset and foo.element
} else {
// item could not be found
}
오프셋 가져 오기
if let fooOffset = array.firstIndex(where: {$0.name == "foo"}) {
// do something with fooOffset
} else {
// item could not be found
}
$0.name == "foo"가 하나의 작업을 $0.name == "boo" 수행하고 다른 작업을 수행
술어와 함께 index사용할 수 있는 방법을 사용할 수 있습니다 Array( 여기서 Apple 문서 참조 ).
func index(where predicate: (Element) throws -> Bool) rethrows -> Int?
구체적인 예를 들면 다음과 같습니다.
스위프트 5.0
if let i = array.firstIndex(where: { $0.name == "Foo" }) {
return array[i]
}
스위프트 3.0
if let i = array.index(where: { $0.name == Foo }) {
return array[i]
}
스위프트 2.0
if let i = array.indexOf({ $0.name == Foo }) {
return array[i]
}
스위프트 3
객체가 필요한 경우 다음을 사용하십시오.
array.first{$0.name == "Foo"}
( "Foo"라는 이름의 개체가 둘 이상 first있으면 지정되지 않은 순서에서 첫 번째 개체를 반환합니다)
array.first {$0.name == "Foo"}
array.first(where: {$0.name == "Foo"})
배열에서 속성을 가진 객체 찾기에 표시된 것처럼 배열을 필터링 한 다음 첫 번째 요소를 선택할 수 있습니다 .
또는 사용자 정의 확장을 정의하십시오.
extension Array {
// Returns the first element satisfying the predicate, or `nil`
// if there is no matching element.
func findFirstMatching<L : BooleanType>(predicate: T -> L) -> T? {
for item in self {
if predicate(item) {
return item // found
}
}
return nil // not found
}
}
사용 예 :
struct T {
var name : String
}
let array = [T(name: "bar"), T(name: "baz"), T(name: "foo")]
if let item = array.findFirstMatching( { $0.name == "foo" } ) {
// item is the first matching array element
} else {
// not found
}
Swift 3 에서는 기존 first(where:)방법을 사용할 수 있습니다 ( 주석에서 언급했듯이 ).
if let item = array.first(where: { $0.name == "foo" }) {
// item is the first matching array element
} else {
// not found
}
array.lazy.filter( predicate ).first됩니까? 작은 배열에 대해 .lazy는 얼마나 효율적입니까?
filter항상 O(n)반면에 findFirstMatching그것은 최악의 시나리오 만의 (당신이 찾고있는 요소가 전혀 배열의 마지막 또는없는 경우). 2. 요청 filter된 요소를 findFirstMatching반환하는 동안 완전히 새로운 필터링 된 요소 배열을 만듭니다 .
스위프트 3.0
if let index = array.index(where: { $0.name == "Foo" }) {
return array[index]
}
스위프트 2.1
swift 2.1에서는 객체 속성 필터링이 지원됩니다. 구조체 또는 클래스의 값을 기반으로 배열을 필터링 할 수 있습니다. 여기 예제가 있습니다.
for myObj in myObjList where myObj.name == "foo" {
//object with name is foo
}
또는
for myObj in myObjList where myObj.Id > 10 {
//objects with Id is greater than 10
}
스위프트 3
Swift 3에서 index (where :)를 사용할 수 있습니다
func index(where predicate: @noescape Element throws -> Bool) rethrows -> Int?
예
if let i = theArray.index(where: {$0.name == "Foo"}) {
return theArray[i]
}
$0.name == "Foo"있습니까?
스위프트 2 이상
당신은 결합 할 수 indexOf및 map한 줄에 "찾기 요소"함수를 작성 할 수 있습니다.
let array = [T(name: "foo"), T(name: "Foo"), T(name: "FOO")]
let foundValue = array.indexOf { $0.name == "Foo" }.map { array[$0] }
print(foundValue) // Prints "T(name: "Foo")"
filter+를 사용하면 first깔끔해 보이지만 filter배열의 모든 요소를 평가합니다. indexOf+ map는 복잡해 보이지만 배열에서 첫 번째 일치 항목이 발견되면 평가가 중지됩니다. 두 가지 방법 모두 장단점이 있습니다.
사용 contains:
var yourItem:YourType!
if contains(yourArray, item){
yourItem = item
}
또는 당신은 마틴이 코멘트에, 당신을 지적 무엇을 시도하고 줄 수있는 filter또 다른 시도 : 배열의 속성과 개체를 찾을 .
item배열의 항목과 동일한 유형 이라고 가정 합니다. 그러나 내가 가진 것은 단지 제목입니다 view.annotation.title. 이 제목으로 배열의 항목을 비교해야합니다.
if contains(yourArray, view.annotation.title) { // code goes here }.
array.index (of : Any)에 액세스하는 또 다른 방법은 객체를 선언하는 것입니다.
import Foundation
class Model: NSObject { }
스위프트 3 :
Swifts 내장 기능을 사용하여 Array에서 사용자 정의 객체를 찾을 수 있습니다.
먼저 커스텀 객체가 Equatable protocol을 준수하는지 확인해야 합니다 .
class Person : Equatable { //<--- Add Equatable protocol
let name: String
var age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
//Add Equatable functionality:
static func == (lhs: Person, rhs: Person) -> Bool {
return (lhs.name == rhs.name)
}
}
Equatable 기능이 객체에 추가되면 Swift는 이제 배열에서 사용할 수있는 추가 속성을 보여줍니다.
//create new array and populate with objects:
let p1 = Person(name: "Paul", age: 20)
let p2 = Person(name: "Mike", age: 22)
let p3 = Person(name: "Jane", age: 33)
var people = [Person]([p1,p2,p3])
//find index by object:
let index = people.index(of: p2)! //finds Index of Mike
//remove item by index:
people.remove(at: index) //removes Mike from array