在Swift

时间:2016-01-14 20:09:10

标签: ios arrays swift struct

我正在尝试过滤包含类的数组,以便只将在另一个数组中找到的类添加到数组中。这就是我到目前为止所做的:

class Match : Equatable {
var name: String
var value: String

init(name: String, value: String) {
    self.name = name
    self.value = value
}

func ==(lhs: Match, rhs: Match) -> Bool {
   return lhs.name == rhs.name && lhs.value == rhs.value
}

// attempt to filter array containing Match structs

let terms = [Match]()
let someOtherObjects = [Match]()
let sampleMatch = Match(name: "someName", value: "someValue")
someOtherObjects.append(sampleMatch)

filteredTerms = terms.filter { term in
   if attemptedCombos.contains(sampleMatch) {
      return true
   }
}

然而,编译器不允许我使用错误构建:

  

"无法转换类型的值'匹配'预期的参数类型   ' @noescape(匹配)抛出 - >布尔'

有什么想法吗?

2 个答案:

答案 0 :(得分:0)

如果MatchEquatable协议确认您的代码应该有效。以下代码成功编译:

class Match : Equatable {
    var name: String
    var value: String

    init(name: String, value: String) {
        self.name = name
        self.value = value
    }
}

func ==(lhs: Match, rhs: Match) -> Bool {
    return lhs.name == rhs.name && lhs.value == rhs.value
}

let sampleMatch1 = Match(name: "someNameA", value: "someValue")
let sampleMatch2 = Match(name: "someNameA", value: "someValue")
let sampleMatch3 = Match(name: "someNameB", value: "someValue")
let sampleMatch4 = Match(name: "someNameC", value: "someValue")

let terms = [sampleMatch1, sampleMatch3]
var someOtherObjects = [sampleMatch2, sampleMatch4]


let filteredTerms = terms.filter { term in
    return someOtherObjects.contains(term)
}

结果是:

enter image description here

答案 1 :(得分:0)

使用Set更新(因为您好像想要两个[Match]数组的交集)。除了Equatable之外,您必须让Match类符合Hashable,以便将其作为Set中的元素的实例。

class Match : Equatable, Hashable {
    var name: String
    var value: String

    init(_ name: String, _ value: String) {
        self.name = name
        self.value = value
    }

    var hashValue: Int {
        get {
            return name.hashValue << 20 + value.hashValue
        }
    }
}

func ==(lhs: Match, rhs: Match) -> Bool {
    return lhs.name == rhs.name && lhs.value == rhs.value
}

示例:

/* Example */
var mySetA : Set<Match> = [Match("foo", "bar"), Match("foo", "foo"), Match("barbar", "foo")]

var mySetB = Set<Match>()
mySetB.insert(Match("barbar", "bar"))
mySetB.insert(Match("bar", "foo"))
mySetB.insert(Match("foo", "bar"))
mySetB.insert(Match("foo", "foo"))

let myIntersect = mySetA.intersect(mySetB)
for match in myIntersect {
    print("name: " + match.name + ", value: " + match.value)
}
/* name: foo, value: foo
   name: foo, value: bar  */

与OP聊天后,我们在聊天中解决了这个问题。我不确定这里的约定是什么,但我将总结OP在聊天中提供的其他信息,以及问题的解决方案。考虑上面的块作为上述问题的解决方案,下面的块作为上述问题的一个非常狭隘的解决方案,补充了OP的更多细节。

  • “过滤器”对象数组与要过滤的数组(Tern)具有不同的类类型(Match),其中这两个类共享一些类属性。
  • 对OP的自然调查是否允许这两个类都有一个共同的超类;它是。
  • 除了上述内容之外,两个类共有的一个属性是自定义枚举类型,由作者在聊天中发布。

使用的最终解决方案,如上所述Set.intersect()

/* custom enum given by OP in chat */
enum Declension : String {
    case firstDeclensionFem = "a:a:am:ae:ae:a:ae:ae:as:arum:is:is"
    case secondDeclensionMasc = "us:er:um:i:o:o:i:i:os:orum:is:is"
    case secondDeclensionNeu = "um:um:um:i:o:o:a:a:a:orum:is:is"
    case thirdDeclensionMasc = " : :em:is:i:e:es:es:es:um:ibus:ibus"
    case thirdDeclensionMascSpecial = " : :em:is:i:e:es:es:es:ium:ibus:ibus"
    case fourthFem = "us:us:um:us:ui:u:us:us:us:uum:ibus:ibus"
    case fourthNeu = "u:u:u:us:u:u:ua:ua:ua:uum:ibus:ibus"
    case fifthMasc = "es:es:em:ei:ei:e:es:es:es:erum:ebus:ebus"
    case unknown

    static let allValues = [firstDeclensionFem, secondDeclensionMasc, secondDeclensionNeu, thirdDeclensionMasc, thirdDeclensionMascSpecial, fourthFem, fourthNeu, fifthMasc]
}

/* use a superclass and let the sets below have members that
   are declared to be of this superclass type                 */
class MyMatchTypes : Equatable, Hashable {
    var latin: String
    var declension: Declension

    init(_ latin: String, _ declension: Declension) {
        self.latin = latin
        self.declension = declension
    }

    var hashValue: Int {
        get {
            return latin.hashValue << 20 + declension.hashValue
        }
    }
}

func ==(lhs: MyMatchTypes, rhs: MyMatchTypes) -> Bool {
    return lhs.latin == rhs.latin && lhs.declension == rhs.declension
}

/* the two classes mentioned in chat: use as subclasses */
class Term : MyMatchTypes {
    var meaning: String
    var notes: String
    var genStem: String

    init(_ latin: String, _ declension: Declension, _ meaning: String, _ genStem: String, _ notes: String) {

        self.meaning = meaning
        self.notes = notes
        self.genStem = genStem

        super.init(latin, declension)

    }
}

class Match : MyMatchTypes {

    // ... add stuff

    // super init is OK
}

/* Example                                         */
/* ----------------------------------------------- */
/* Set of `Match` objects */
var mySetA = Set<MyMatchTypes>()
mySetA.insert(Match("foo", Declension.firstDeclensionFem))
mySetA.insert(Match("bar", Declension.fourthFem))
mySetA.insert(Match("foofoo", Declension.fourthFem))
mySetA.insert(Match("barbar", Declension.fifthMasc))

/* Set of `Term` objects */
var mySetB = Set<MyMatchTypes>()
mySetB.insert(Term("fooshy", Declension.fourthFem, "a", "b", "c"))
mySetB.insert(Term("barbar", Declension.fifthMasc, "a", "b", "c"))
mySetB.insert(Term("bar", Declension.fourthFem, "a", "b", "c"))
mySetB.insert(Term("foofoo", Declension.firstDeclensionFem, "a", "b", "c"))
mySetB.insert(Term("foobar", Declension.fourthFem, "a", "b", "c"))

/* compute intersection */
let myIntersect = mySetA.intersect(mySetB)
for obj in myIntersect {
    print("latin: " + obj.latin + ", declension: \(obj.declension)")
}
/* latin: barbar, declension: fifthMasc
   latin: bar,    declension: fourthFem    */