我有一个带有属性 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!)
}
你能帮我做吗?
谢谢,抱歉我的英语不好......
最佳答案
您第一次使用 map 没问题,因为您的数组非常小,您希望创建一个新数组然后检索 minElement()
。
但是,关于您的第二个任务,不要仅仅使用 map 来设置属性。请记住,.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 map 函数。 ( 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 等高阶函数的真正好处不一定是性能。这是通过消除样板代码而获得的简洁性。使用高阶函数,您可以更快地切入要点,同时仍然生成可读代码。
在我的测试中,性能差异可以忽略不计。
关于快速使用 map 设置属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34531300/