我有两个由不同结构构成的数组,并且它们在数组的不同位置都具有相同的信息。
我尝试使用if语句进行两次for-in循环,以检查它们是否具有相同的值,但是我在其他语言(如PHP)中执行此操作的方式无效。
请帮助我,这是到目前为止我得到的:
单个文件
struct oneStruct {
var oneTitle: String
var onePic: UIImage?
var oneCategory: String
}
class OneSingleton {
static let sharedInstance = OneSingleton()
private init() {}
var oneArray: [OneStruct] = [//you get the gist, this is full of array stuff]
}
两个文件
struct TwoStruct {
var twoName: String
var twoPic: UIImage?
var twoSubject: String
var twoStuff1: String
// etc. I can't get into much more here, sorry.
}
class TwoSingleton {
static let sharedInstance = TwoSingleton()
private init() {}
var twoArray: [TwoStruct] = [//you get the gist, this is full of array stuff as well]
}
视图控制器
//the singleton stuff is needed
var oneArray = [OneSingleton.sharedInstance.oneArray]
var twoArray = [TwoSingleton.sharedInstance.twoArray]
var filterArray: [TwoStruct] = []
override func viewDidLoad() {
super.viewDidLoad()
for two in twoArray {
for one in oneArray {
if two == one {
filterArray.append(contentsOf: two)
}
}
}
}
这给了我一个编译错误
二进制运算符'=='不能应用于类型'[TwoStruct]'和'[OneStruct]'的操作数
我希望这一切都有道理。
谢谢。
答案 0 :(得分:-1)
比较两者的实现Equatable
并将lhs或rhs更改为另一个对象
struct OneStruct :Equatable {
var value1: String
var value2: UIImage? /// image comparsion is not an easy way you may add id of image
var value3: String
// also you can omit any static method part from any class
static func ==(lhs: TwoStruct, rhs: OneStruct) -> Bool {
return lhs.value1 == rhs.value1 && lhs.value3 == rhs.value3
}
}
struct TwoStruct :Equatable {
var value1: String
var value2: UIImage? /// image comparsion is not an easy way you may add id of image
var value3: String
// also you can omit any static method part from any class
static func ==(lhs: OneStruct, rhs: TwoStruct) -> Bool {
return lhs.value1 == rhs.value1 && lhs.value3 == rhs.value3
}
}
//
let s1 = OneStruct(value1: "", value2: UIImage.init(named: ""), value3: "")
let s2 = TwoStruct(value1: "", value2: UIImage.init(named: ""), value3: "")
if s1 == s2 {
}
答案 1 :(得分:-1)
对于每个OneStruct
和TwoStruct
类型,您似乎都有一个要用于比较的属性。 category
和subject
。因此,首先,为这两个属性设计两个协议的蓝图:
protocol Categorizable {
var category: String { get }
}
protocol Subjectable {
var subject: String { get }
}
就本示例而言,OneStruct
和TwoStruct
的最少示例将分别符合Categorizable
和Subjectable
:
struct OneStruct: Categorizable {
var category: String
init(_ category: String) { self.category = category }
}
struct TwoStruct: Subjectable {
var subject: String
init(_ subject: String) { self.subject = subject }
}
现在,当比较两种不同类型时,我们真的不想谈论平等,而是可以比较这两种类型的实例的等效类或双向谓词。因此,让我们定义例如一个双向谓词,可用于比较分别符合Categorizable
和Subjectable
的两个实例:
struct BiPredicate<T: Categorizable, U: Subjectable> {
static func compare(_ lhs: T, _ rhs: U) -> Bool {
return lhs.category == rhs.subject
}
static func compare(_ lhs: U, _ rhs: T) -> Bool {
return compare(rhs, lhs)
}
}
根据您自己的示例代码,似乎您希望两个过滤器分别基于是否对TwoStruct
数组(即符合Subjectable
的类型的数组)进行过滤,数组,在OneStruct
数组(即符合Categorizable
的类型的数组)中存在一个成员,对于该成员,等效类或双向谓词为true。
/// Returns `lhs` argument filtered based on its BiPredicate intersection
/// with the `rhs` argument.
/// Time complexity: O(n^2)
func filterByIntersect<T: Subjectable, U: Categorizable>(_ lhs: [T], over rhs: [U]) -> [T] {
return lhs.filter { l in rhs.contains { r in BiPredicate.compare(l, r) } }
}
我们可以将其用作:
let oneArray = [OneStruct("foo"), OneStruct("bar"), OneStruct("baz"), OneStruct("bax")]
let twoArray = [TwoStruct("baxx"), TwoStruct("foo"), TwoStruct("bax")]
let result = filterByIntersect(twoArray, over: oneArray)
for twoElement in result { print(twoElement.subject) } /* foo
bax */
现在,这主要是一个有趣的练习,但是最后却得到了很多样板代码,这些代码本来应该是一个简单的任务。您总是可以删除泛型,而只需使用一个简单的函数来测试OneStruct
和TwoStruct
上的单个等效类:
func compareCategoryWithSubject(_ lhs: OneStruct, _ rhs: TwoStruct) -> Bool {
return lhs.category == rhs.subject
}
/// Returns `lhs` argument filtered based on intersection over comparing
/// the `subject` properties of the elements of `lhs` with the `category`
/// properties of the elements of `rhs`.
/// Time complexity: O(n^2)
func filterByIntersect(_ lhs: [TwoStruct], over rhs: [OneStruct]) -> [TwoStruct] {
return lhs.filter { l in rhs.contains { r in
compareCategoryWithSubject(r, l) } }
}
或者,对于一种可能甚至更简单且渐近地更高效的方法,请将所有逻辑放入filterByIntersect(...)
函数中:
/// Returns `lhs` argument filtered based on intersection over comparing
/// the `subject` properties of the elements of `lhs` with the `category`
/// properties of the elements of `rhs`.
/// Time complexity: O(n) [contains(_:) is O(1) for Set)
func filterByIntersect(_ lhs: [TwoStruct], over rhs: [OneStruct]) -> [TwoStruct] {
let rhsCategories = Set(rhs.map { $0.category })
return lhs.filter { l in rhsCategories.contains(l.subject) }
}
以上两种方法均产生与上述相同的结果:
let oneArray = [OneStruct("foo"), OneStruct("bar"), OneStruct("baz"), OneStruct("bax")]
let twoArray = [TwoStruct("baxx"), TwoStruct("foo"), TwoStruct("bax")]
let result = filterByIntersect(twoArray, over: oneArray)
for twoElement in result { print(twoElement.subject) } /* foo
bax */