我有两个数组:
fruitsArray = ["apple", "mango", "blueberry", "orange"]
vegArray = ["tomato", "potato", "mango", "blueberry"]
我怎样才能得到这两个数组中的常见项目列表
ouptput = ["mango", "blueberry"]
我不能使用 if contains(array, string)
因为我想比较 2 个数组。
最佳答案
您还可以使用 filter
和 contains
结合:
let fruitsArray = ["apple", "mango", "blueberry", "orange"]
let vegArray = ["tomato", "potato", "mango", "blueberry"]
// only Swift 1
let output = fruitsArray.filter{ contains(vegArray, $0) }
// in Swift 2 and above
let output = fruitsArray.filter{ vegArray.contains($0) }
// or
let output = fruitsArray.filter(vegArray.contains)
Set
对比Array
用于公共(public)元素的单次计算
我们考虑以下代码片段:
let array1: Array = ...
let array2: Array = ...
// `Array`
let commonElements = array1.filter(array2.contains)
// vs `Set`
let commonElements = Array(Set(array1).intersection(Set(array2)))
// or (performance wise equivalent)
let commonElements: Array = Set(array1).filter(Set(array2).contains)
我用 Int
做了一些(人工)基准测试和空头/多头 String
s(10 到 100 Character
s)(全部随机生成)。我总是用 array1.count == array2.count
我得到以下结果:
如果你有超过critical #(number of) elements
转换为 Set
更可取
data | critical #elements
-------------|--------------------
Int | ~50
short String | ~100
long String | ~200
结果说明
使用 Array
方法使用“蛮力”搜索,其中有 time complexity O(N^2)
其中 N = array1.count = array2.count
这与 Set
形成对比方法 O(N)
.但是从 Array
的转换至 Set
来回对于大数据来说非常昂贵,这解释了 critical #elements
的增加用于更大的数据类型。
结论
对于小Array
Array
大约有 100 个元素方法很好,但对于较大的方法,您应该使用 Set
方法。
如果你想多次使用这个“公共(public)元素”操作,建议使用 Set
s only 如果可能(元素的类型必须是 Hashable
)。
最后的评论
来自 Array
的转换至 Set
从 Set
转换时有点贵至 Array
相比之下非常便宜。
使用 filter
与 .filter(array1.contains)
性能比 .filter{ array1.contains($0) }
更快因为:
- 最后一个创建一个新的闭包(只有一次)而第一个只传递一个函数指针
- 对于最后一个,闭包的调用创建了一个额外的堆栈帧,这会花费空间和时间(多次:
O(N)
)
关于arrays - 如何在 Swift 中获取 2 数组的公共(public)元素列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32439289/