一尘不染

如何在Swift中获取2数组的公共元素列表?

swift

我有两个数组:

fruitsArray = ["apple", "mango", "blueberry", "orange"]
vegArray = ["tomato", "potato", "mango", "blueberry"]

我如何获得这两个数组中的常见项目列表

ouptput = ["mango", "blueberry"]

我无法使用,if contains(array, string)因为我想比较2个数组。


阅读 272

收藏
2020-07-07

共1个答案

一尘不染

您还可以结合使用filtercontains

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)

SetArray仅计算共同元素相比

我们考虑以下代码片段:

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)

我用Intshort和long Strings(10到100
Characters)(全部随机生成)做了一些(人工)基准测试。我总是用array1.count == array2.count

我得到以下结果:

如果您不只critical #(number of) elements转换为a,则更Set可取

data         |  critical #elements
-------------|--------------------
         Int |        ~50
short String |       ~100
 long String |       ~200

结果说明

使用该Array方法使用“蛮力”搜索,该搜索具有时间复杂度
O(N^2)N = array1.count = array2.count而与该Set方法相反O(N)。然而从转换ArraySet和背部是这解释了增加大数据非常昂贵的`critical

elements`更大的数据类型。


结论

对于Array具有约100个元素的小s,该Array方法很好,但对于较大的s,则应使用该Set方法。

如果您想多次使用此“常见元素”运算,则建议 仅* 在可能的情况下使用Sets (元素的类型必须为)。 *Hashable

结束语

ArraySet的转换比较昂贵,而从Set到的转换Array则非常便宜。

filter与with一起使用比在以下.filter(array1.contains)情况下性能更快.filter{ array1.contains($0) }

  • 最后一个创建一个新的闭包( 仅一次 ),而第一个仅传递一个函数指针
  • 对于最后一个封闭件的调用创建花费空间和时间的附加堆栈帧( 多次O(N)
2020-07-07