如何比较两个数组的元素

时间:2022-02-27 08:40:36

I want to compare the elements of two arrays and check if they are equal. I already tried various solutions but nothing really works.

我想比较两个数组的元素,并检查它们是否相等。我已经尝试了各种解决方案但没有真正有效。

I tried the solution from How to compare two array of objects?

我试过如何比较两个对象数组的解决方案?

This is my object:

这是我的目标:

struct AccountBalance: Decodable {
    let balance: Double
    let currency: String

    init(balance: Double, currency: String ) {
        self.currency = currency
        self.balance = balance
    }

    enum CodingKeys: String, CodingKey {
        case currency = "Currency"
        case balance = "Balance"
    }
}

This is the code from the link I tried:

这是我试过的链接中的代码:

let result = zip(accountBalance, getsSaved).enumerate().filter() {
                $1.0 == $1.1
                }.map{$0.0}

But I get this error:

但我得到这个错误:

Closure tuple parameter '(offset: Int, element: (AccountBalance, AccountBalance))' does not support destructuring with implicit parameters

4 个解决方案

#1


6  

Array provides a function elementsEqual which is able to compare two arrays without explicitly conforming to Equatable:

Array提供了一个函数elementsEqual,它能够比较两个数组而不显式符合Equatable:

let result = accountBalance.elementsEqual(getsSaved) {
    $0.balance == $1.balance && $0.currency == $1.currency
}

Edit:

If you want to have the equality result regardless of the order of objects in the array then you can just add sort with each of the arrays.

如果要获得相等结果而不管数组中对象的顺序如何,那么您只需为每个数组添加排序。

let result = accountBalance.sorted { $0.balance < $1.balance }.elementsEqual(getsSaved.sorted { $0.balance < $1.balance }) {
    $0.balance == $1.balance && $0.currency == $1.currency
}

#2


1  

I'm not sure about what the rest of your code does, but making the parameters explicit does make XCode happy:

我不确定你的其余代码是做什么的,但是使参数显式化会让XCode感到满意:

let result = zip(accountBalance, getsSaved).enumerated().filter() { (arg) -> Bool in
    let (_, (balance1, balance2)) = arg     
    return balance1.balance == balance2.balance
}.map{ $0.0 }`

Tried (_, (balance1, balance2)) -> Bool in directly, but it wouldn't let me either

试过(_,(balance1,balance2)) - >直接布尔,但它也不会让我

#3


1  

I will suggest you implement the accepted answer of the link you provided because it controls that both arrays are the same size and it orders them.

我建议你实现你提供的链接的接受答案,因为它控制两个数组的大小相同并且它们对它们进行排序。

But if you want that your code works I solved like this:

但如果你想要你的代码工作,我解决了这样的:

如何比较两个数组的元素

In order to have control of the comparison your struct should implement the Equatable protocol and overload the operator ==

为了控制比较,你的struct应该实现Equatable协议并重载operator ==

extension AccountBalance : Equatable {}

func ==(lhs: AccountBalance, rhs: AccountBalance) -> Bool {
    return lhs.balance == rhs.balance && lhs.currency == rhs.currency
}

Then compare both arrays and check if contains false, if it does, one or more items in the array aren't the same.

然后比较两个数组并检查是否包含false,如果包含false,则数组中的一个或多个项不相同。

let result = !zip(accountBalance, getsSaved).enumerated().map() {
    $1.0 == $1.1
}.contains(false)

Hope it helps you

希望它能帮到你

#4


1  

I am guessing two arrays should be considered equal when they contain the same elements, regardless of ordering.

我猜两个数组在包含相同元素时应该被认为是相等的,无论排序如何。

First, implement Equatable and Hashable.

首先,实现Equatable和Hashable。

I am using hashValue as an id so I can sort the arrays first.

我使用hashValue作为id,所以我可以先对数组进行排序。

Here is what your AccountBalance class should look like:

以下是您的AccountBalance类应如下所示:

struct AccountBalance: Decodable, Equatable, Hashable {


   // Important parts!
    var hashValue: Int{
        return balance.hashValue ^ currency.hashValue &* 1677619
    }
    static func == (lhs: AccountBalance, rhs: AccountBalance)  -> Bool{
        return lhs.balance == rhs.balance && lhs.currency == rhs.currency
    }

}

Then create an algorithm that sorts the ararys and then check each elements by one by by if the contents are the same.

然后创建一个算法,对ararys进行排序,然后逐个检查每个元素是否内容相同。

Here is the function that take use of Equatable and Hashable.

这是使用Equatable和Hashable的函数。

func isEqual(arr1: [AccountBalance], arr2: [AccountBalance]) -> Bool{

    if arr1.count != arr1.count{
        return false
    }

    let a = arr1.sorted(){
        $0.hashValue > $1.hashValue
    }

    let b = arr2.sorted(){
        $0.hashValue > $1.hashValue
    }

    let result = zip(a, b).enumerated().filter() {
        $1.0 == $1.1
        }.count

    if result == a.count{
        return true
    }

    return false
}

#1


6  

Array provides a function elementsEqual which is able to compare two arrays without explicitly conforming to Equatable:

Array提供了一个函数elementsEqual,它能够比较两个数组而不显式符合Equatable:

let result = accountBalance.elementsEqual(getsSaved) {
    $0.balance == $1.balance && $0.currency == $1.currency
}

Edit:

If you want to have the equality result regardless of the order of objects in the array then you can just add sort with each of the arrays.

如果要获得相等结果而不管数组中对象的顺序如何,那么您只需为每个数组添加排序。

let result = accountBalance.sorted { $0.balance < $1.balance }.elementsEqual(getsSaved.sorted { $0.balance < $1.balance }) {
    $0.balance == $1.balance && $0.currency == $1.currency
}

#2


1  

I'm not sure about what the rest of your code does, but making the parameters explicit does make XCode happy:

我不确定你的其余代码是做什么的,但是使参数显式化会让XCode感到满意:

let result = zip(accountBalance, getsSaved).enumerated().filter() { (arg) -> Bool in
    let (_, (balance1, balance2)) = arg     
    return balance1.balance == balance2.balance
}.map{ $0.0 }`

Tried (_, (balance1, balance2)) -> Bool in directly, but it wouldn't let me either

试过(_,(balance1,balance2)) - >直接布尔,但它也不会让我

#3


1  

I will suggest you implement the accepted answer of the link you provided because it controls that both arrays are the same size and it orders them.

我建议你实现你提供的链接的接受答案,因为它控制两个数组的大小相同并且它们对它们进行排序。

But if you want that your code works I solved like this:

但如果你想要你的代码工作,我解决了这样的:

如何比较两个数组的元素

In order to have control of the comparison your struct should implement the Equatable protocol and overload the operator ==

为了控制比较,你的struct应该实现Equatable协议并重载operator ==

extension AccountBalance : Equatable {}

func ==(lhs: AccountBalance, rhs: AccountBalance) -> Bool {
    return lhs.balance == rhs.balance && lhs.currency == rhs.currency
}

Then compare both arrays and check if contains false, if it does, one or more items in the array aren't the same.

然后比较两个数组并检查是否包含false,如果包含false,则数组中的一个或多个项不相同。

let result = !zip(accountBalance, getsSaved).enumerated().map() {
    $1.0 == $1.1
}.contains(false)

Hope it helps you

希望它能帮到你

#4


1  

I am guessing two arrays should be considered equal when they contain the same elements, regardless of ordering.

我猜两个数组在包含相同元素时应该被认为是相等的,无论排序如何。

First, implement Equatable and Hashable.

首先,实现Equatable和Hashable。

I am using hashValue as an id so I can sort the arrays first.

我使用hashValue作为id,所以我可以先对数组进行排序。

Here is what your AccountBalance class should look like:

以下是您的AccountBalance类应如下所示:

struct AccountBalance: Decodable, Equatable, Hashable {


   // Important parts!
    var hashValue: Int{
        return balance.hashValue ^ currency.hashValue &* 1677619
    }
    static func == (lhs: AccountBalance, rhs: AccountBalance)  -> Bool{
        return lhs.balance == rhs.balance && lhs.currency == rhs.currency
    }

}

Then create an algorithm that sorts the ararys and then check each elements by one by by if the contents are the same.

然后创建一个算法,对ararys进行排序,然后逐个检查每个元素是否内容相同。

Here is the function that take use of Equatable and Hashable.

这是使用Equatable和Hashable的函数。

func isEqual(arr1: [AccountBalance], arr2: [AccountBalance]) -> Bool{

    if arr1.count != arr1.count{
        return false
    }

    let a = arr1.sorted(){
        $0.hashValue > $1.hashValue
    }

    let b = arr2.sorted(){
        $0.hashValue > $1.hashValue
    }

    let result = zip(a, b).enumerated().filter() {
        $1.0 == $1.1
        }.count

    if result == a.count{
        return true
    }

    return false
}