我有一个带有属性fontSize的4数组segmentedControl,我想一次为所有4个元素设置此属性的值。
通常,我希望将此循环转换为唯一的句子:
// set identic font size for all segments (first, get the minimum font size and then set it for all segments)
let minimumSize = (segmentedControlAnimated.segments.map{$0.titleLabel!.fontSize}).minElement()
for i in 0..<segmentedControlAnimated.segmentContent.text.count {
segmentedControlAnimated.segments[i].titleLabel!.font = UIFont(name: "HelveticaNeue-Medium", size: minimumSize!)
}
你能帮帮我吗?
谢谢,对不起我的英语不好......
答案 0 :(得分:2)
你第一次使用地图很好,因为你的数组很小,而你想要创建一个新的数组然后检索minElement()
。
但是,关于第二个任务,不要仅使用地图来设置属性。请记住,.map
会创建一个替换原始对象的全新对象。像.forEach
这样的东西会更合适,因为它会更新原始对象。
当您打算转换某些内容时使用.map
,例如,将整数数组转换为字符串数组。
当您只需要更改属性时,请使用.forEach
。
我需要看到更多的代码才能确定,但从理论上讲,这样的东西应该可以用来更新你的属性:
segmentedControlAnimated.segments.forEach { item in
return item.titleLabel!.font = UIFont(name: "HelveticaNeue-Medium", size: minimumSize!)
}
或
segmentedControlAnimated.segments.forEach { return $0.titleLabel!.font = UIFont(name: "HelveticaNeue-Medium", size: minimumSize!) }
基于评论的更多细节:
要了解传统的for-in循环和更高阶函数(如.map)之间的性能差异,请查看标准库中定义的Swifts映射函数。 (source)
public func map<T>( @noescape transform: (Generator.Element) throws -> T
) rethrows -> [T] {
let initialCapacity = underestimateCount()
var result = ContiguousArray<T>()
result.reserveCapacity(initialCapacity)
var generator = generate()
// Add elements up to the initial capacity without checking for regrowth.
for _ in 0..<initialCapacity {
result.append(try transform(generator.next()!))
}
// Add remaining elements, if any.
while let element = generator.next() {
result.append(try transform(element))
}
return Array(result)
}
请注意,它几乎就是你在代码中编写的内容。因此,这里最大的收获是使用更高阶函数(如map,filter,reduce和forEach)的真正好处不一定是性能。这是通过消除样板代码得到的简洁性。使用更高阶函数,您可以更快地达到这一点,同时仍然可以生成可读代码。
在我的测试中,性能差异可以忽略不计。