I have an 4-array segmentedControl with a property fontSize and I want to set the value of this property for all the 4 elements at once.
Typically, I wish to transform this loop to an unique sentence :
// 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!)
}
Can you help me to do that ?
Thanks, and sorry for my poor English...
Your first use of map is fine since your array is very small and you're desire is to create a new array to then retrieve a minElement().
However, regarding your second task, don't use map just to set a property. Remember that .map creates a brand new object that replaces your original. Something like .forEach would be more suitable since it updates your original object.
Use .map when you intend on transforming something, for instance, transforming an array of integers into an array of strings.
Use .forEach when you just need to change a property a bunch of items.
I'd need to see more of you code to know for sure, but in theory, something like this should work to update your property:
segmentedControlAnimated.segments.forEach { item in
return item.titleLabel!.font = UIFont(name: "HelveticaNeue-Medium", size: minimumSize!)
}
or
segmentedControlAnimated.segments.forEach { return $0.titleLabel!.font = UIFont(name: "HelveticaNeue-Medium", size: minimumSize!) }
More detail based on comments:
To get an idea of the performance differences between a traditional for-in loop and higher order functions like .map, take a look at Swifts map function as defined in the standard library. (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)
}
Notice that it's pretty much what you'd write in your code anyway. So, the big take away here is that the real benefit in using higher order functions like map, filter, reduce and forEach is not necessarily performance. It's the terseness you get by the elimination of boilerplate code. With higher order functions you get to the point quicker while still producing readable code.
In my tests, the performance difference is negligible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With