在Swift数组上设置操作(联合,交集)?


100

我是否可以使用任何标准库调用来对两个数组执行集合操作,或者自己实现这种逻辑(在功能上和效率上都尽可能理想)?


如果您想自己动手,可以在字典的顶部实现一个集合。
CodaFi

@CodaFi您是说通过使用按键来确保唯一性吗?
devios1 2014年

您可以只使用`Dictionary <String,Void>吗?
大卫·贝里

Answers:


184

是的,Swift Set上课了。

let array1 = ["a", "b", "c"]
let array2 = ["a", "b", "d"]

let set1:Set<String> = Set(array1)
let set2:Set<String> = Set(array2)

Swift 3.0+可以对集合执行以下操作:

firstSet.union(secondSet)// Union of two sets
firstSet.intersection(secondSet)// Intersection of two sets
firstSet.symmetricDifference(secondSet)// exclusiveOr

Swift 2.0可以计算数组参数:

set1.union(array2)       // {"a", "b", "c", "d"} 
set1.intersect(array2)   // {"a", "b"}
set1.subtract(array2)    // {"c"}
set1.exclusiveOr(array2) // {"c", "d"}

Swift 1.2+可以根据设置进行计算:

set1.union(set2)        // {"a", "b", "c", "d"}
set1.intersect(set2)    // {"a", "b"}
set1.subtract(set2)     // {"c"}
set1.exclusiveOr(set2)  // {"c", "d"}

如果使用自定义结构,则需要实现Hashable。

感谢Michael Stern在Swift 2.0更新的评论中。

感谢Amjad Husseini在Hashable信息的评论中。


8
请注意,至少从Swift 2.0开始,您可以将数组作为参数传递给这些函数。因此,除了上面显示的形式外,set1.union(array2)set1.exclusiveOr(array2)都是合法的。
Michael Stern 2015年

如果要相交5个数组怎么办?还是6?如果数组数量未知怎么办?
内森·麦卡斯克

2
@Nathan取决于设置的操作。例如,集合并集和集合交集是可交换的和关联的,因此您可以使用迭代或链接来处理许多集合。或者,您可以创建使用var args的自定义方法,例如Set union_all(...)和intersect_all(...)。
joelparkerhenderson

如果您的数组包含重复的值,例如,确定$ 0是否是$ 1的字谜,输入的字符可能具有重复的字母,该怎么办?
戴夫·克里曼

1
如果您使用的是自定义结构,则必须遵循Hashable,如果您使用的是复杂的结构,这可能会很烦人
Amjad Husseini

0

没有任何标准库调用,但是您可能需要查看ExSwift库。它在数组上包含了许多新功能,包括差异,交集和并集。


1
注意事项:我一直在使用ExSwift来处理Swift 1.x,但是对于Swift 2.x来说似乎已经很破了,并且在撰写本文之时还没有几个月。有大量的叉子可能会引起更多关注。
罗宾·马查格


0

我知道的最有效的方法是使用godel编号。Google用于godel编码。

这个想法是这样。假设您有N个可能的数字,并且需要对它们进行设置。例如,N = 100,000,并希望设置{1,2,3},{5、88、19000}等集合。

想法是将N个质数的列表保留在内存中,对于给定的{a,b,c,...}集,您将其编码为

 prime[a]*prime[b]*prime[c]*...

因此,您将一个集合编码为BigNumber。尽管BigNumbers的操作比Integers的操作要慢,但事实仍然非常快。

要组合2套A,B,您需要

  UNITE(A, B) = lcm(a, b)

A和B的最小公倍数,因为A和B是集合,并且都是数字。

为了使交叉路口

 INTERSECT(A, B) = gcd (a, b)

最大公约数。

等等。

这种编码称为godelization,您可以在Google上搜索更多的内容,所有使用Frege逻辑编写的算术语言都可以通过数字方式进行编码。

要获得该操作的成员资格?这很简单-

ISMEMBER(x, S) = remainder(s,x)==0

要获得红衣主教,它要复杂一些-

CARDINAL(S) = # of prime factors in s

您将代表素数乘积集合的数字S分解,并添加它们的指数。如果该集合不允许重复,则您将拥有所有指数1。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.