Swift使用map设置属性

3
我有一个包含4个选项的分段控件,其中有一个名为fontSize的属性。我希望一次性设置这个属性的值,使得所有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!)
}

你能帮我做这件事吗?

谢谢,抱歉我的英语不太好...

1个回答

2

由于您的数组很小,且您的目的是创建一个新数组,然后检索minElement(),因此您对map的第一次使用是正确的。

但是,在涉及到您的第二个任务时,请不要仅仅使用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等高阶函数之间的性能差异,请看一下Swift标准库中定义的map函数。(来源

  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等高阶函数的真正好处不一定是性能,而是通过消除样板代码获得的简洁性。使用高阶函数可以更快地到达目的地,同时仍然产生可读的代码。
在我的测试中,性能差异可以忽略不计。

非常感谢您的详细解释!我之前不知道forEach,它真是太棒了! - Nahouto
当我发现它时,我也感到惊讶。我认为它是为了让Swift开发人员使用高阶函数编写更简洁的代码而创建的。很高兴它能奏效! - Dan Beaulieu
它可能比循环更有效率,不是吗? - Nahouto
在大多数情况下,像forEach这样的高阶函数与它们的for-in循环同行相比,速度几乎可以忽略不计(实际上,forEach只是一个for-in循环)。然而,在更新属性的情况下,forEach将比.map更快,因为它不需要创建新对象。 - Dan Beaulieu
非常感谢您提供这么详细的解释! - Nahouto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接