Swift에는 Underscore.js의 _.findWhere 와 같은 것이 있습니까?
유형의 구조체 배열이 있고 배열에 속성이 같은 T
구조체 객체가 포함되어 있는지 확인하고 싶습니다 .name
Foo
사용하려고 find()
하고 filter()
기본 유형, 예와하지만, 그들은 단지 일 String
또는 Int
. Equitable
프로토콜 또는 이와 유사한 것을 준수하지 않는 경우 오류가 발생 합니다.
Swift에는 Underscore.js의 _.findWhere 와 같은 것이 있습니까?
유형의 구조체 배열이 있고 배열에 속성이 같은 T
구조체 객체가 포함되어 있는지 확인하고 싶습니다 .name
Foo
사용하려고 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