Riv*_*era 6 arrays find indexof swift
虽然find(["a", "b"], "c")没有问题,但在尝试查找结构数组中的结构索引时出错:
struct Score
{
//...
}
var scores: [Score] = //...
var score: Score = //...
find(self.scores, score) // Error: Cannot invoke 'find' with an argument list of type '([Score], Score)'
Run Code Online (Sandbox Code Playgroud)
我可能是一个问题,结构默认情况下无法相互比较.但改变Scores定义class
给我同样的错误.
Air*_*ity 14
编辑:从Swift 2.0开始,现在有一个内置版本,find它需要一个闭包,所以你不必编写自己的 - 但也find已经重命名indexOf,现在是协议扩展CollectionType,所以你称之为像一个方法:
// if you make `Score` conform to `Equatable:
if let idx = self.scores.indexOf(score) {
}
// or if you don't make it Equatable, you can just use a closure:
// (see original answer below for why you might prefer to do this)
if let idx = scores.indexOf({$0.scoreval == 3}) {
}
Run Code Online (Sandbox Code Playgroud)
原始2.0之前的答案
虽然答案表明让你的课程Equatable可以很好地工作,但在选择这样做之前我会建议你谨慎一点.原因在于,正如文档所述,等同性意味着可替代性,并且您的==运算符必须是自反的,对称的和可传递的.如果您不遵守这一点,在使用类似算法等时可能会遇到一些非常奇怪的行为.如果在非最终类上实现equals,sort请特别谨慎Equatable.如果您确定自己能够满足要求,那么就去做吧find.
如果没有,你可以考虑的替代方法是编写一个应该在标准库中的函数,但不是,这是一个find需要关闭的函数:
func find<C: CollectionType>(source: C, match: C.Generator.Element -> Bool) -> C.Index {
for idx in indices(source) {
if match(source[idx]) { return idx }
}
return nil
}
Run Code Online (Sandbox Code Playgroud)
完成后,您可以提供您喜欢的任何匹配条件.例如,如果您的对象是类,则可以使用引用相等:
let idx = find(scores) { $0 === $1 }
Run Code Online (Sandbox Code Playgroud)
该函数的接口find是/是:
func find<C : CollectionType where C.Generator.Element : Equatable>(domain: C,
value: C.Generator.Element) -> C.Index?
Run Code Online (Sandbox Code Playgroud)
这是说的CollectionType的C话,必须要有元素Equatable,此外,该value还必须Equatable.
[ 注意Swift 3.0:从Swift 3.0开始,你需要使用有index两种变体的功能.在第一个中,您将提供自己的谓词:
func index(where: (Self.Generator.Element) -> Bool) -> Self.Index?
Run Code Online (Sandbox Code Playgroud)
在第二个中,您的元素需要是等同的:
// Where Generator.Element : Equatable
func index(of: Self.Generator.Element) -> Self.Index?
Run Code Online (Sandbox Code Playgroud)
如果您决定前往该equatable路线,则以下情况适用.
注意结束 ]
您的Score结构不是Equatable,因此错误. 你需要弄清楚分数是否相等才意味着什么. 也许这是一些数字'得分'; 也许它是'得分'和'用户ID'.这取决于你的Score抽象.一旦你知道,你实现==使用:
func == (lhs:Score, rhs:Score) -> Bool {
return // condition for what it means to be equal
}
Run Code Online (Sandbox Code Playgroud)
注意:如果您使用class并且因此得分具有"身份",那么您可以将其实现为:
func == (lhs:Score, rhs:Score) -> Bool { return lhs === rhs }
Run Code Online (Sandbox Code Playgroud)
你的字符串示例String是因为Equatable.如果您查看Swift库代码,您将看到:
extension String : Equatable {}
func ==(lhs: String, rhs: String) -> Bool
Run Code Online (Sandbox Code Playgroud)