如何比较两个数组中的元素

9
我想比较两个数组的元素并检查它们是否相等。我已经尝试了各种解决方案,但都没有成功。
我尝试了来自如何比较两个对象数组?的解决方案。
这是我的对象:
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"
    }
}

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

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

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

但是我遇到了这个错误:
Closure tuple parameter '(offset: Int, element: (AccountBalance, AccountBalance))' does not support destructuring with implicit parameters

好问题!我还在想如何首先对数组进行排序。 - user3773246
5个回答

16

Array 提供了一个函数 elementsEqual,可以在不必显式遵循 Equatable 的情况下比较两个数组:

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

编辑:

如果你希望在数组中无论对象的顺序如何都能得到相等的结果,则可以在每个数组上添加排序。

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

谢谢您的回答,这只有在数组先排序的情况下才会返回 true。 - PaFi

3
我猜当两个数组包含相同元素,无论顺序如何,它们应该被认为是相等的。
首先,请实现EquatableHashable
我使用hashValue作为标识符,这样我就可以首先对数组进行排序。
以下是您的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
    }

}

然后创建一个将数组排序并逐个检查每个元素是否内容相同的算法。

这里是使用 EquatableHashable 的函数。

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
}

谢谢您的回答,我有一个问题:这行代码到底是在做什么呢?“return balance.hashValue ^ currency.hashValue &* 1677619” - PaFi
你正在给 struct 分配一个 hashValue。它用于首先对数组进行排序。 - user3773246

2
我建议你实现你提供的链接中的被接受答案,因为它可以控制两个数组的大小并将它们排序。

但是,如果你希望你的代码能够运行,我是这样解决的:

enter image description here

为了能够控制比较,您的结构体应该实现Equatable协议并重载运算符==。
extension AccountBalance : Equatable {}

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

然后比较这两个数组并检查是否包含false,如果包含,则表示数组中至少有一个或多个项目不相同。
let result = !zip(accountBalance, getsSaved).enumerated().map() {
    $1.0 == $1.1
}.contains(false)

希望它能对你有所帮助。

你的答案是错误的。如果两个数组没有排序,结果就是false。 - user3773246

0

我不确定你的代码的其余部分是做什么的,但是显式地指定参数确实可以让XCode感到满意:

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

尝试直接使用(_, (balance1, balance2)) -> Bool,但它也不让我这样做。


0

带有多个数组的示例:

import Foundation

let arr1: [String?] = ["word", nil, "word3", "word4"]
let arr2: [Double?] = [1.01, 1.02, nil, 1.04]
let arr3: [Int?] = [nil, 2, 3, 4]

var tuple1: [(title: String, number: String, coord: String)] = []

let countArray = arr1.count

for element in 0..<countArray {
    tuple1.append((arr1[element].map 
{String($0)} ?? "", arr2[element].map 
{String($0)} ?? "", arr3[element].map 
{String($0)} ?? ""))
}

print(tuple1)

打印结果:

[(title: "word1", number: "1.01", coord: ""), (title: "", number: "1.02", coord: "2"), (title: "word3", number: "", coord: "3"), (title: "word4", number: "1.04", coord: "4")]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接