Compare value from two struct in swift

2019-03-02 09:33发布

问题:

I have two struct and two arrays corresponding to it and I am trying to compare the two array values and print it in one filtered array i did try and use filter but its giving me an error I want to compare an id from both the struct and get one single array

Struct ONE

struct One {
    let ID: String
    let name: String
    let lastName: String
}

Array One

var oneData = [One]()
oneData = [One(ID: "1", name: "hello1", lastName: "last2"), One(ID: "1", name: "hello2", lastName: "last2"), One(ID: "2", name: "hello3", lastName: "last3"), One(ID: "3", name: "hello4", lastName: "last4")]

Struct TWO

struct Two {
    let ID: String
    let name2: String
    let lastName2: String
}

Array Two

var twoData = [Two]()
twoData = [Two(ID: "1", name2: "hello1", lastName2: "last1"), Two(ID: "2", name2: "hello2", lastName2: "last2"), Two(ID: "3", name2: "hello3", lastName2: "last3"), Two(ID: "4", name2: "hello4", lastName2: "last4"), Two(ID: "5", name2: "hello5", lastName2: "last5")]

My filtered Array

var mainArray = [Two]()

Code to that I used to filter which is giving me an error

mainArray = oneData.filter{ $0.ID == twoData.contains(where: $0.ID)}

回答1:

To get objects of array oneData whose ID matched with ID of any object from array twoData. You can do following:

    // Array One
    var oneData = [One]()
    oneData = [One(ID: "1", name: "hello1", lastName: "last2"),
               One(ID: "1", name: "hello2", lastName: "last2"),
               One(ID: "2", name: "hello3", lastName: "last3"),
               One(ID: "3", name: "hello4", lastName: "last4")]

    // Array Two
    var twoData = [Two]()
    twoData = [Two(ID: "1", name2: "hello1", lastName2: "last1"),
               Two(ID: "2", name2: "hello2", lastName2: "last2"),
               Two(ID: "3", name2: "hello3", lastName2: "last3"),
               Two(ID: "4", name2: "hello4", lastName2: "last4"),
               Two(ID: "5", name2: "hello5", lastName2: "last5")]

    let mainArray = oneData.filter { i in twoData.contains{ i.ID == $0.ID } }
    print(mainArray)



回答2:

If you're looking to filter oneData to only those elements that have a matching ID field in twoData, you want:

let mainArray = oneData.filter { i in twoData.contains { i.ID == $0.ID } }


回答3:

your mainArray is of type [Two] and you are trying to put data of type [One] in mainArray. According to swift this is wrong you cannot do this.

you can do it in another way let me post it in 10 mins

You have 2 options now either make common protocol like and confirm the structs with it and make the mainArray of that protocol type as follows:

protocol Identifiable {
    var id: String {get set}
    var name: String {get set}
    var lastName: String {get set}
}

struct One: Identifiable{
    var id: String
    var name: String
    var lastName: String
}

struct Two: Identifiable{
    var id: String
    var name: String
    var lastName: String
}

now make the main Array of type Identifiable as follows

 var mainArray = [Identifiable]()

and filter as follows

 mainArray = oneData.filter{ i in twoData.contains { i.id == $0.id }}

Another option is do not make the protocol Identifiable and let the structs be as they were before. And just make the mainArray of type [One] just dont forget to change the change in filter line i.e From this:

 mainArray = oneData.filter{ $0.ID == twoData.contains(where: $0.ID)}

To this:

 mainArray = oneData.filter{ i in twoData.contains { i.id == $0.id }}


回答4:

Swift standard library has an Equatable protocol that we can adopt by adding the static == operator function to our type in an extension. You should create only one structure like below

struct Employee {
  let id: String
  let name: String
  var lastName: String
}

extension Employee: Equatable {
  static func == (lhs: Employee, rhs: Employee) -> Bool {
    return lhs.name == rhs.name &&
    lhs.id == rhs.id &&
    lhs.lastName == rhs.lastName
  }
}


标签: swift swift4