Swift 3 - 两个字典数组之间的差异

时间:2022-04-30 12:47:30

I have two arrays of dictionaries:

我有两个字典数组:

let arrayA = [["name1": "email1"], ["name2": "email2"]]
let arrayB = [["name1": "email1"], ["name3": "email3"]]

I want to compare them and get another two arrays: arrayC should have the elements in arrayA but not in arrayB, and arrayD should have the elements in arrayB but not in arrayA:

我想比较它们并得到另外两个数组:arrayC应该有arrayA中的元素而不是arrayB中的元素,而arrayD应该有arrayB中的元素而不是arrayA中的元素:

let arrayC = [["name2": "email2"]]
let arrayD = [["name3": "email3"]]

How can I do this taking into the consideration large arrays?

如何考虑大型阵列呢?

2 个解决方案

#1


8  

Here you go

干得好

let arrayA = [["name1": "email1"], ["name2": "email2"]]
let arrayB = [["name1": "email1"], ["name3": "email3"]]

let arrayC = arrayA.filter{
    let dict = $0
    return !arrayB.contains{ dict == $0 }
}

let arrayD = arrayB.filter{
    let dict = $0
    return !arrayA.contains{ dict == $0 }
}

#2


3  

I know this answer may be complicating things and that you can use filter but...have you considered using Sets instead of Arrays?

我知道这个答案可能会使事情变得复杂,你可以使用过滤器但是......你考虑过使用集合代替数组吗?

Sets can give you operations for finding elements in setA but not in setB or elements in setA and setB out of the box.

集合可以为您提供在setA中查找元素但不在setB中的操作或setA和setB中的元素的操作。

There are a few caveats about sets though. As it says in The Swift Programming Guide

虽然有一些关于集合的警告。正如它在Swift编程指南中所说的那样

A set stores distinct values of the same type in a collection with no defined ordering. You can use a set instead of an array when the order of items is not important, or when you need to ensure that an item only appears once.

集合在集合中存储相同类型的不同值,没有定义的顺序。当项目的顺序不重要时,或者当您需要确保项目仅出现一次时,您可以使用集合而不是数组。

notice from the above:

上述通知:

  • Distinct: Meaning no duplicates
  • 区别:意思是没有重复

  • No definded ordering: Means that you cannot expect your sets to be in order
  • 没有明确的订购:意味着你不能指望你的套装有序

Also, notice this (also from The Swift Programming Guide):

另外,请注意这一点(也来自The Swift Programming Guide):

A type must be hashable in order to be stored in a set—that is, the type must provide a way to compute a hash value for itself.

类型必须是可散列的才能存储在集合中 - 即,类型必须提供计算自身散列值的方法。

If you can live with that...then sets are a fine solution I think.

如果你可以忍受......那么我认为套装是一个很好的解决方案。

Here is an example...I created a simple Email struct and made that implement Hashable:

这是一个例子......我创建了一个简单的Email结构,并实现了Hashable:

struct Email {
    let name: String
    let email: String
}

extension Email: Hashable {
    var hashValue: Int {
        return "\(name)\(email)".hashValue
    }

    static func ==(lhs: Email, rhs: Email) -> Bool {
         return lhs.name == rhs.name && lhs.email == rhs.email
    }
}

And that can then be used like so:

然后可以这样使用:

let arrayA = [Email(name: "name1", email: "email1"), Email(name: "name2", email: "email2")]
let arrayB = [Email(name: "name1", email: "email1"), Email(name: "name3", email: "email3")]
let setA = Set(arrayA)
let setB = Set(arrayB)

let inBothAAndB = setA.intersection(setB) //gives me an Email with "name1", "email1"
let inAButNotB = setA.subtracting(setB) //gives me an Email with "name2", "email2"
let inBButNotA = setB.subtracting(setA) //gives me an Email with "name3", "email3"

So...I don't know if that confuses things for you or makes things harder or maybe impossible (if you're data can contain more than one element with the same name and email for instance) but...I just thought you should consider sets :)

所以...我不知道这是否会让你感到困惑,或者让事情变得更难或者更不可能(例如,如果你的数据可以包含多个具有相同名称和电子邮件的元素)但是......我只是想到了你应该考虑集:)

Hope that helps you.

希望对你有所帮助。

#1


8  

Here you go

干得好

let arrayA = [["name1": "email1"], ["name2": "email2"]]
let arrayB = [["name1": "email1"], ["name3": "email3"]]

let arrayC = arrayA.filter{
    let dict = $0
    return !arrayB.contains{ dict == $0 }
}

let arrayD = arrayB.filter{
    let dict = $0
    return !arrayA.contains{ dict == $0 }
}

#2


3  

I know this answer may be complicating things and that you can use filter but...have you considered using Sets instead of Arrays?

我知道这个答案可能会使事情变得复杂,你可以使用过滤器但是......你考虑过使用集合代替数组吗?

Sets can give you operations for finding elements in setA but not in setB or elements in setA and setB out of the box.

集合可以为您提供在setA中查找元素但不在setB中的操作或setA和setB中的元素的操作。

There are a few caveats about sets though. As it says in The Swift Programming Guide

虽然有一些关于集合的警告。正如它在Swift编程指南中所说的那样

A set stores distinct values of the same type in a collection with no defined ordering. You can use a set instead of an array when the order of items is not important, or when you need to ensure that an item only appears once.

集合在集合中存储相同类型的不同值,没有定义的顺序。当项目的顺序不重要时,或者当您需要确保项目仅出现一次时,您可以使用集合而不是数组。

notice from the above:

上述通知:

  • Distinct: Meaning no duplicates
  • 区别:意思是没有重复

  • No definded ordering: Means that you cannot expect your sets to be in order
  • 没有明确的订购:意味着你不能指望你的套装有序

Also, notice this (also from The Swift Programming Guide):

另外,请注意这一点(也来自The Swift Programming Guide):

A type must be hashable in order to be stored in a set—that is, the type must provide a way to compute a hash value for itself.

类型必须是可散列的才能存储在集合中 - 即,类型必须提供计算自身散列值的方法。

If you can live with that...then sets are a fine solution I think.

如果你可以忍受......那么我认为套装是一个很好的解决方案。

Here is an example...I created a simple Email struct and made that implement Hashable:

这是一个例子......我创建了一个简单的Email结构,并实现了Hashable:

struct Email {
    let name: String
    let email: String
}

extension Email: Hashable {
    var hashValue: Int {
        return "\(name)\(email)".hashValue
    }

    static func ==(lhs: Email, rhs: Email) -> Bool {
         return lhs.name == rhs.name && lhs.email == rhs.email
    }
}

And that can then be used like so:

然后可以这样使用:

let arrayA = [Email(name: "name1", email: "email1"), Email(name: "name2", email: "email2")]
let arrayB = [Email(name: "name1", email: "email1"), Email(name: "name3", email: "email3")]
let setA = Set(arrayA)
let setB = Set(arrayB)

let inBothAAndB = setA.intersection(setB) //gives me an Email with "name1", "email1"
let inAButNotB = setA.subtracting(setB) //gives me an Email with "name2", "email2"
let inBButNotA = setB.subtracting(setA) //gives me an Email with "name3", "email3"

So...I don't know if that confuses things for you or makes things harder or maybe impossible (if you're data can contain more than one element with the same name and email for instance) but...I just thought you should consider sets :)

所以...我不知道这是否会让你感到困惑,或者让事情变得更难或者更不可能(例如,如果你的数据可以包含多个具有相同名称和电子邮件的元素)但是......我只是想到了你应该考虑集:)

Hope that helps you.

希望对你有所帮助。