如何在 Swift 中获取 2 个数组的公共元素列表? [英] How to get list of common elements of 2 array in Swift?

查看:19
本文介绍了如何在 Swift 中获取 2 个数组的公共元素列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个数组:

fruitsArray = ["apple", "mango", "blueberry", "orange"]vegArray = [番茄"、土豆"、芒果"、蓝莓"]

我怎样才能得到这两个数组中的常见项目列表

输出= [芒果",蓝莓"]

我不能使用 if contains(array, string) 因为我想比较 2 个数组.

解决方案

你也可以结合使用filtercontains:

let fruitsArray = ["apple", "mango", "blueberry", "orange"]let vegArray = [番茄"、土豆"、芒果"、蓝莓"]//只有 Swift 1让输出 = FruitsArray.filter{ contains(vegArray, $0) }//在 Swift 2 及更高版本中让输出 = FruitsArray.filter{ vegArray.contains($0) }//或者让输出 = FruitsArray.filter(vegArray.contains)

<小时>

Set vs Array 用于公共元素的单一计算

我们考虑以下代码片段:

let array1: Array = ...让数组 2:数组 = ...//`数组`让 commonElements = array1.filter(array2.contains)//vs `Set`让 commonElements = Array(Set(array1).intersection(Set(array2)))//或(性能明智的等价物)让 commonElements: Array = Set(array1).filter(Set(array2).contains)

我已经用 Int 和短/长 Strings(10 到 100 个 Characters)(全部随机生成).我总是使用 array1.count == array2.count

我得到以下结果:

如果您有多个 critical #(number of) 元素 转换为 Set 是可取的

数据 |关键#elements-------------|------------国际|~50短字符串 |~100长字符串 |~200

结果说明

使用 Array 方法使用具有 时间复杂度的蛮力"搜索 O(N^2) 其中 N = array1.count = array2.countSet 方法形成对比 <代码>O(N).然而,从 ArraySet 的转换对于大数据来说是非常昂贵的,这解释了对于更大的数据类型 critical #elements 的增加.

<小时>

结论

对于大约 100 个元素的小型 Array 方法,Array 方法很好,但对于较大的元素,您应该使用 Set 方法.>

如果你想多次使用这个公共元素"-操作,建议尽可能使用Sets only(元素的类型必须是Hashable).

最后的评论

ArraySet 的转换有点昂贵,而从 SetArray 的转换是在对比很便宜.

使用 filter.filter(array1.contains) 在性能上比 .filter{ array1.contains($0) } 更快,因为:

  • 最后一个创建一个新的闭包(仅一次),而第一个只传递一个函数指针
  • 对于最后一个闭包的调用会创建一个额外的堆栈帧,这会消耗空间和时间(多次:O(N))

I have two arrays:

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

How can I get the list of common items in those two array which gives

ouptput = ["mango", "blueberry"]

I can't use if contains(array, string) as I want to compare 2 arrays.

解决方案

You can also use filter and contains in conjunction:

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 vs Array for a single computation of common elements

We consider the following code snippet:

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)

I have made some (artificial) benchmarks with Int and short/long Strings (10 to 100 Characters) (all randomly generated). I always use array1.count == array2.count

I get the following results:

If you have more than critical #(number of) elements converting to a Set is preferable

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

Explanation of the results

Using the Array approach uses "Brute force"-search which has time complexity O(N^2) where N = array1.count = array2.count which is in contrast to the Set approach O(N). However the conversion from Array to Set and back is very expensive for large data which explains the increase of critical #elements for bigger data types.


Conclusion

For small Arrays with about 100 elements the Array approach is fine but for larger ones you should use the Set approach.

If you want to use this "common elements"-operation multiple times it is advisable to use Sets only if possible (the type of the elements has to be Hashable).

Final Remarks

A conversion from Array to Set is kind of expensive while the conversion from Set to Array is in contrast very inexpensive.

Using filter with .filter(array1.contains) is performance wise faster than .filter{ array1.contains($0) } since:

  • the last one creates a new closure (only once) whereas the first one passes only a function pointer
  • for the last one the call of the closure creates an additional stack frame which costs space and time (multiple times: O(N))

这篇关于如何在 Swift 中获取 2 个数组的公共元素列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆