1

for some reason I cannot compare 2 different arrays, for example:

if (self.data.contains(where: self.compareData)){
}

throws:

Cannot convert value of type '[dataModel]' to expected argument type '(dataModel) throws -> Bool'

and trying to compare them using == also throws an error as Binary operator '==' cannot be applied to operands of type '((dataModel) throws -> Bool) throws -> Bool' and '[dataModel]'

the arrays are formatted as:

var data : [dataModel] = [dataModel] ()
var compareData : [dataModel] = [dataModel]()

I'm checking to see if that array is set to the same array that was sent before replacing data and updating a table.

EDIT: here is the dataModels code:

class dataModel {
   var teamName : String = ""

   var aboutTeams : String = ""

   // var rate : String = "5" // team Rating

   var messageID : String = ""
}
koen
  • 5,383
  • 7
  • 50
  • 89
JohnM
  • 73
  • 7

4 Answers4

1

That's because that function you are trying to use requires an NSPredicate.

One way to check if an array contains a subset of another array would be to do the following:

var dataSet = Set(data)
var compareDataSet = Set(compareData)

if compareDataSet.isSubsetOf(dataSet) {
   // Do something
}

EDIT: Your class needs to conform to equatable

class dataModel: Equatable {

    var teamName : String = ""

    var aboutTeams : String = ""

   // var rate : String = "5" // team Rating

    var messageID : String = ""

    override func isEqual(_ object: Any?) -> Bool {
        if let object = object as? dateModel {
            return self.teamName == object.teamName && self.aboutTeams == object.aboutTeams && self.messageID == object.messageID
        } else {
            return false
        }
    } 
}
rs7
  • 1,618
  • 1
  • 8
  • 16
1

You can compare properties of elements within a dataModel if they are inherently comparable/equatable, like String or Int. If you want to be able to test equality for specific elements within the dataModel array itself, then you will have to make your dataModel conform to Equatable.

I believe the problem you are facing has to do with making your dataModel class or struct conform to Equatable, or with how you are populating data and compareData.

This basic example should give you an idea of how to do it. It tests equality for different portions of the data (smaller and larger entities):

struct dataModel: Equatable {
    let id: Int
    let name: String
}

var data : [dataModel] = [dataModel]()

var compareData : [dataModel] = [dataModel]()

data = [
    dataModel(id: 5, name: "five"),
    dataModel(id: 3, name: "three")
]

compareData = [
    dataModel(id: 5, name: "five"),
    dataModel(id: 2, name: "three")
]

if data[0].id == compareData[0].id {
    print("First item ID is equal")
}

if data[0].name == compareData[0].name {
    print("First item name is equal")
}

if data[0] == compareData[0] {
    print("First item of both data and compareData are equal")
}

if data == compareData {
    print("Data Arrays are equal")
} else {
    print("Data Arrays are not equal")
}

I saw that you just showed the code for your DataModel (class should usually be capitalized) so here's a more customized example using your actual implementation of the class:

class DataModel: Equatable {
    static func == (lhs: DataModel, rhs: DataModel) -> Bool {
        guard lhs.aboutTeams == rhs.aboutTeams else {return false}
        guard lhs.messageID == rhs.messageID else {return false}
        guard lhs.teamName == rhs.teamName else {return false}
        return true
    }

    var teamName : String = ""
    var aboutTeams : String = ""
    var messageID : String = ""
}

var data : [DataModel] = [DataModel]()

var compareData : [DataModel] = [DataModel]()

data = [
    DataModel(),
    DataModel()
]
data[0].teamName = "raptors"
data[0].messageID = "5"

compareData = [
    DataModel(),
    DataModel()
]
compareData[0].teamName = "raptors"
compareData[0].messageID = "4"

if data[0].teamName == compareData[0].teamName {
    print("Element 0 team names are equal")
} else {
    print("Element 0 team names are not equal")
}

if data[0].messageID == compareData[0].messageID {
    print("Elemeant 0 message IDs are equal")
} else {
    print("Elemeant 0 message IDs are not equal")
}

if data[1] == compareData[1] {
    print("Element 1 of data and compareData are equal")
}

if data == compareData {
    print("Arrays are equal")
} else {
    print("Arrays are not equal")
}

The console output is:

Element 0 team names are equal
Elemeant 0 message IDs are not equal
Element 1 of data and compareData are equal
Arrays are not equal

Hope this helps!

Wattholm
  • 849
  • 1
  • 4
  • 8
1

You can try with this example.

import UIKit


class ViewController: UIViewController, NavDelegate {
    var data : [dataModel] = [dataModel]()
    var compareData : [dataModel] = [dataModel]()

    override func viewDidLoad() {
        super.viewDidLoad()

        data = [
            dataModel(teamName: "cyber1", aboutTeams: "strong", messageID: "1001"),
            dataModel(teamName: "cyber1", aboutTeams: "good", messageID: "1002")
        ]

        compareData = [
            dataModel(teamName: "cyber1", aboutTeams: "strong", messageID: "1001"),
            dataModel(teamName: "cyber1", aboutTeams: "good 2", messageID: "1002")
        ]


        let dataSet = Set(data)
        let compareDataSet = Set(compareData)

        if compareDataSet == dataSet {
           print("compareDataSet and dataSet are equal")
        }else{
            print("compareDataSet and dataSet are not equal")
        }
    }

    struct dataModel: Hashable {
        var teamName : String = ""
        var aboutTeams : String = ""
        var messageID : String = ""
    }
}
AMIT
  • 906
  • 1
  • 8
  • 20
0

If all you are requiring is to see if two arrays are equal, you can do it with a simple function:

func compare<T: Equatable>(_ array1: [T], _ array2: [T] ) -> Bool {
   guard array1.count == array2.count else {return false}
   for i in 0 ..< array1.count {
      if array1[i] != array2[i] { return false}
   }
   return true
}

You could even build this as an extension of Array

extension Array where Element: Equatable{
   func compare(to array: [Element]) -> Bool {
      guard array.count == self.count else {return false}
      for i in 0 ..< array.count {
            if array[i] != self[i] { return false}
      }
      return true
   }
}

The compiler won't let you compare two arrays of different types.

flanker
  • 3,840
  • 1
  • 12
  • 20