仅基于 X 在数组中查找 cgpoint
Finding cgpoint in array based only on X
我在 Swift 中有一个 CGPoints 数组。
我想仅使用 X 值在数组中找到一个点(它们都有唯一的 X 值,所以这应该不是问题),然后从中获取 Y 值。
我还想要一种方法来仅查看它是否包含具有我正在寻找的 X 值的点,例如只关心 X 的 .contains。
您可以使用 indexOf:
函数通过谓词查找数组中某项的索引。从那里,您可以使用索引访问该项目。
这实际上回答了你的两个问题,因为它要么是 returns 带有你的 X 值的 CGPoint
的索引,要么是 returns nil
.
let index = pointArray.indexOf {
[=10=].x == xToFind
}
if let index = index {
let point = pointArray[index]
// Do something with the point that has the x-value you wanted
} else {
// There is no point in the array with the x-value you wanted
}
处理此类问题的一种过于复杂但很好的方法是使用协议和扩展。
如果我们创建一个 XYType
protocol
,它具有 typealias Element
和 x
以及 y
类型的 Element
属性,我们可以扩展SequenceType
封装了filter
和contains
方法。
protocol XYType {
typealias Element
var x : Element { get set }
var y : Element { get set }
}
extension CGPoint : XYType {}
现在是真正的方法:
扩展 SequenceType
但使用约束。 Generator.Element
应该是 XYType
而 Generator.Element.Element
(XYType
的 Element
)应该是 Equatable
.
实际的过滤函数有点复杂。但本质上它使用它获得的函数作为参数 includeElement: (Self.Generator.Element.Element) throws -> Bool
并且如果它是真的它附加到一个副本。到底它returns那个copy.
extension SequenceType where Generator.Element : XYType, Generator.Element.Element : Equatable {
// this function just mimics the regular filter.
func filterByX(@noescape includeElement: (Self.Generator.Element.Element) throws -> Bool) rethrows -> [Self.Generator.Element] {
var copy : [Generator.Element] = []
for element in self where try includeElement(element.x) {
do {
let include = try includeElement(element.x)
if include {
copy.append(element)
}
} catch {
continue
}
}
return copy
}
func filterByY(@noescape includeElement: (Self.Generator.Element.Element) throws -> Bool) rethrows -> [Self.Generator.Element] {
var copy : [Generator.Element] = []
for element in self where try includeElement(element.y) {
do {
let include = try includeElement(element.y)
if include {
copy.append(element)
}
} catch {
continue
}
}
return copy
}
}
对contains
做同样的事情
extension SequenceType where Generator.Element : XYType, Generator.Element.Element : Equatable {
func containsX(@noescape predicate: (Self.Generator.Element.Element) throws -> Bool) rethrows -> Bool {
for element in self {
do {
let result = try predicate(element.x)
if result {
return true
}
} catch {
continue
}
}
return false
}
func containsY(@noescape predicate: (Self.Generator.Element.Element) throws -> Bool) rethrows -> Bool {
for element in self {
do {
let result = try predicate(element.y)
if result {
return true
}
} catch {
continue
}
}
return false
}
}
测试:
let points = [CGPoint(x: 1, y: 1),CGPoint(x: 2, y: 2),CGPoint(x: 3, y: 3),CGPoint(x: 4, y: 4)]
// CGPoint(2,2)
points.filterByY { (y) -> Bool in
y == 2
}
// false
points.containsX { (x) -> Bool in
x == 5
}
P.S。 :
你也可以这样做,它有点短:
let filtered = points.filter {
[=14=].x == 2
}
let contains = points.contains {
[=14=].x == 3
}
我在 Swift 中有一个 CGPoints 数组。
我想仅使用 X 值在数组中找到一个点(它们都有唯一的 X 值,所以这应该不是问题),然后从中获取 Y 值。
我还想要一种方法来仅查看它是否包含具有我正在寻找的 X 值的点,例如只关心 X 的 .contains。
您可以使用 indexOf:
函数通过谓词查找数组中某项的索引。从那里,您可以使用索引访问该项目。
这实际上回答了你的两个问题,因为它要么是 returns 带有你的 X 值的 CGPoint
的索引,要么是 returns nil
.
let index = pointArray.indexOf {
[=10=].x == xToFind
}
if let index = index {
let point = pointArray[index]
// Do something with the point that has the x-value you wanted
} else {
// There is no point in the array with the x-value you wanted
}
处理此类问题的一种过于复杂但很好的方法是使用协议和扩展。
如果我们创建一个 XYType
protocol
,它具有 typealias Element
和 x
以及 y
类型的 Element
属性,我们可以扩展SequenceType
封装了filter
和contains
方法。
protocol XYType {
typealias Element
var x : Element { get set }
var y : Element { get set }
}
extension CGPoint : XYType {}
现在是真正的方法:
扩展 SequenceType
但使用约束。 Generator.Element
应该是 XYType
而 Generator.Element.Element
(XYType
的 Element
)应该是 Equatable
.
实际的过滤函数有点复杂。但本质上它使用它获得的函数作为参数 includeElement: (Self.Generator.Element.Element) throws -> Bool
并且如果它是真的它附加到一个副本。到底它returns那个copy.
extension SequenceType where Generator.Element : XYType, Generator.Element.Element : Equatable {
// this function just mimics the regular filter.
func filterByX(@noescape includeElement: (Self.Generator.Element.Element) throws -> Bool) rethrows -> [Self.Generator.Element] {
var copy : [Generator.Element] = []
for element in self where try includeElement(element.x) {
do {
let include = try includeElement(element.x)
if include {
copy.append(element)
}
} catch {
continue
}
}
return copy
}
func filterByY(@noescape includeElement: (Self.Generator.Element.Element) throws -> Bool) rethrows -> [Self.Generator.Element] {
var copy : [Generator.Element] = []
for element in self where try includeElement(element.y) {
do {
let include = try includeElement(element.y)
if include {
copy.append(element)
}
} catch {
continue
}
}
return copy
}
}
对contains
extension SequenceType where Generator.Element : XYType, Generator.Element.Element : Equatable {
func containsX(@noescape predicate: (Self.Generator.Element.Element) throws -> Bool) rethrows -> Bool {
for element in self {
do {
let result = try predicate(element.x)
if result {
return true
}
} catch {
continue
}
}
return false
}
func containsY(@noescape predicate: (Self.Generator.Element.Element) throws -> Bool) rethrows -> Bool {
for element in self {
do {
let result = try predicate(element.y)
if result {
return true
}
} catch {
continue
}
}
return false
}
}
测试:
let points = [CGPoint(x: 1, y: 1),CGPoint(x: 2, y: 2),CGPoint(x: 3, y: 3),CGPoint(x: 4, y: 4)]
// CGPoint(2,2)
points.filterByY { (y) -> Bool in
y == 2
}
// false
points.containsX { (x) -> Bool in
x == 5
}
P.S。 :
你也可以这样做,它有点短:
let filtered = points.filter {
[=14=].x == 2
}
let contains = points.contains {
[=14=].x == 3
}