例如,以哈希集h = [1,2,3,4,5]
为例,目的是计算唯一元素i的数量,使得h.contains(i+1)
。
我可以使用reduce()
写下快速代码
h.reduce(0,{h.contains($1+1) ? $0 + 1 : $0})
但是,如果h是一个包含重复项而不是哈希集的数组怎么办?我首先需要将其转换为哈希集,然后使用上面的表达式:
Set(h).reduce(0,{Set(h).contains($1+1) ? $0 + 1 : $0})
但是通过这种方式,我们计算了{carpsen90所指出的Set(h)的Set(h).count + 1
次,有没有办法像这样编写代码
Set(h).reduce(0,{self.contains($1+1) ? $0 + 1 : $0})
是否不使用临时变量来存储Set(h)
?
答案 0 :(得分:0)
每次调用Set(h)
都会计算一个新集合,因此在您的示例Set(h).reduce(0,{Set(h).contains($1+1) ? $0 + 1 : $0})
中,Set(h)
将被计算h.count + 1
次。让变量让set = Set(h)是这里的方法:
let set = Set(h)
let result = set.reduce(0) {set.contains($1+1) ? $0 + 1 : $0}
他是获得所需结果的替代方式:
让我们创建一个字典,指示是否在h
中出现了一个数字:
var dict = [Int: Bool].init(minimumCapacity: h.count)
for x in h {
if dict[x] == nil {
dict[x] = true
}
}
然后,对于每个h
元素,检查其后继者是否出现在字典中:
var count = 0
for entry in dict {
if dict[entry.key + 1] == true {
count += 1
}
}
您可以检查结果:
print(count) //4
答案 1 :(得分:0)
这里的问题是您的数组可能包含重复项,并且要过滤重复项,最简单的方法是将其转换为Set。正确的做法是将集合保存在新变量中,因此这是不可避免的。
尽管您仍可以使用reduce方法,而无需将数组转换为如下所示的集合:
var tempH = [Int]()
let c = h.reduce(0) { (result, item) in
if (!tempH.contains(item)) {
tempH.append(item)
return h.contains(item+1) ? (result + 1) : result
}
else {return result}
}
但是,正如您在上面的代码中注意到的那样,我们必须使用一个临时数组来跟踪我们的重复项。因此,在这里似乎不可避免要有额外的变量。尽管以上代码中没有使用Set。