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对公共元素的单次计算
我们考虑以下代码片段:
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)
func arrayOfCommonElements <T, U where T: SequenceType, U: SequenceType, T.Generator.Element: Equatable, T.Generator.Element == U.Generator.Element> (lhs: T, rhs: U) -> [T.Generator.Element] {
var returnArray:[T.Generator.Element] = []
for lhsItem in lhs {
for rhsItem in rhs {
if lhsItem == rhsItem {
returnArray.append(lhsItem)
}
}
}
return returnArray
}
用法类似:
var one = ["test2", "dog", "cat"]
var other = ["test2", "cat", "dog"]
var result = arrayOfCommonElements(one,other)
print(result) //prints [test2, dog, cat]
func arrayOfNonCommonElements <T, U where T: SequenceType, U: SequenceType, T.Generator.Element: Equatable, T.Generator.Element == U.Generator.Element> (lhs: T, rhs: U) -> [T.Generator.Element] {
var returnArray:[T.Generator.Element] = []
var found = false
for lhsItem in lhs {
for rhsItem in rhs {
if lhsItem == rhsItem {
found = true
break
}
}
if (!found){
returnArray.append(lhsItem)
}
found = false
}
for rhsItem in rhs {
for lhsItem in lhs {
if rhsItem == lhsItem {
found = true
break
}
}
if (!found){
returnArray.append(rhsItem)
}
found = false
}
return returnArray
}
let fruitsArray = ["apple", "mango", "blueberry", "orange"]
let vegArray = ["tomato", "potato", "mango", "blueberry"]
//You can using filter function
let commonArray = fruitsArray.filter { fruit in
vegArray.contains(fruit)
}
print(commonArray)
7条答案
按热度按时间kgsdhlau1#
您也可以将
filter
和contains
结合使用:Set
与Array
对公共元素的单次计算我们考虑以下代码片段:
我用
Int
和短/长String
(10到100个Character
)(全部随机生成)做了一些(人工)基准测试。我得到以下结果:
如果你有超过
critical #(number of) elements
转换为一个Set
是可取的结果说明
使用
Array
方法使用“暴力”搜索,其具有time complexityO(N^2)
,其中N = array1.count = array2.count
,这与Set
方法O(N)
形成对比。然而,对于大型数据,从Array
到Set
的转换以及从Set
到O(N^2)
的转换非常昂贵,这解释了对于更大的数据类型,critical #elements
的增加。结论
对于具有大约100个元素的小
Array
,Array
方法是合适的,但是对于较大的元素,您应该使用Set
方法。如果要多次使用此“公共元素”操作,建议在可能的情况下仅使用
Set
s****(元素类型必须为Hashable
)。最后备注
从
Array
到Set
的转换是一种昂贵的转换,而从Set
到Array
的转换相比之下是非常便宜的。将
filter
与.filter(array1.contains)
配合使用,在性能方面比.filter{ array1.contains($0) }
快,原因如下:dpiehjr42#
将它们转换为Set并使用intersect()函数:
5cg8jx4n3#
您不需要Set(正如上面的注解所提到的)。
你可以使用一个 generic 函数,类似于Apple在他们的Swift Tour中使用的**,从而避免强制转换**:
此函数可以接受任意两个数组(SequenceTypes),如果它们的任何元素相同,则返回true。
您可以简单地修改此泛型函数,将字符串数组打包并返回。
例如这样的例子:
用法类似:
这里额外的好处是,这个函数也可以处理所有相同类型的数组。所以,如果你以后需要比较两个
[myCustomObject]
数组,一旦它们都符合equatable,你就都set了!(双关语)编辑:(对于 * 非 * 公共元素)您可以这样做
不过,这种实现很难看。
ruoxqz4g4#
一种通用方法,灵感来自The Swift Programming Language (Swift 3)练习:
然后,按如下方式使用它:
vdzxcuhz5#
以下代码适用于swift 4:
vmpqdwk36#
以下内容适用于swift 4,5
输出:[“芒果”,“蓝莓”]
eivgtgni7#
使用Set和交集,如下所示: