85

I have a code that I need to run exactly n times in Swift. What is the shortest possible syntax for that?

I am currently using the for loop but it is a lot of typing.

for i in 0..<n { /* do something */ } 

Is there a shorter/nicer way for running same code n times in Swift?

8
  • 23
    I would say that is already pretty damn short. How much shorter do you want to go? Commented May 31, 2015 at 5:02
  • @hexagonstar a want to push Swift to its theoretical limit if it's not reached already here. Commented May 31, 2015 at 5:06
  • 1
    You want to run it infinite times, well try using a while Commented May 31, 2015 at 5:07
  • 3
    for i in 0 ..< n is already the absolute minimum. You could use a while loop, incrementing a counter but that wouldn't be shorter. Commented May 31, 2015 at 5:08
  • 5
    @Jonny that’s what the _ is for. for _ in 0..<n { } Commented Feb 17, 2019 at 20:06

14 Answers 14

98
+100

Speaking of syntax, you might define your own shortest syntax:

extension Int { func times(_ f: () -> ()) { if self > 0 { for _ in 0..<self { f() } } } func times(_ f: @autoclosure () -> ()) { if self > 0 { for _ in 0..<self { f() } } } } var s = "a" 3.times { s.append(Character("b")) } s // "abbb" var d = 3.0 5.times(d += 1.0) d // 8.0 
Sign up to request clarification or add additional context in comments.

6 Comments

repeat is a keyword in Swift 2, so you have to choose a different name. – Adding @escape and perhaps throws/rethrows might also make sense.
As well as this spectacular answer, be sure to check out another spectacular solution to a similar problem.
Why are there two versions of the func, one with and one without @autoclosure?
It is possible to use Swift keywords as function names in Swift. Put a backslash tick before and after the name, as we do here to style text as code: repeat.
|
53

Sticking with a for loop - you could extend Int to conform to SequenceType to be able to write:

for i in 5 { /* Repeated five times */ } 

To make Int conform to SequenceType you'll could do the following:

extension Int : SequenceType { public func generate() -> RangeGenerator<Int> { return (0..<self).generate() } } 

3 Comments

It is sick! A small point, for me "i in 5" would mean i in 12345 rather than i in 01234. (I'd use a psuedo-keyword more like, perhaps, "upTo" for 01234.) Of course, opinions would differ on this, but bear it in mind.
Because writing an extension to Int and using it obscurely with for i in 5 is easier than for i in 0..<5?
The point wasn't to make it readable, it was to make it short, for fun
43

You have several ways of doing that:

Using for loops:

for i in 1...n { `/*code*/` } 

for i = 0 ; i < n ; i++ { `/*code*/` } 

for i in n { `/*code*/` } 

using while loops:

var i = 0 while (i < n) { `/*code*/` ` i++` } 

var i = 0 repeat { ` /*code*/` `i++` } while(i <= n) 

3 Comments

for i in n to work you must use @ABakerSmith's answer: stackoverflow.com/a/30560726/2500457
for i in 1...n crashes for n = 0. So if this a valid input, make sure to use one of the other methods.
the ++ operator was removed from Swift
33
for _ in 1...5 { //action will be taken 5 times. } 

Comments

19

you could use functional programming on a range instead of a loop, for shorter and "nicer" syntax for example

(0..<n).forEach{print("Index: \($0)")} 

Other answers mention defining your own syntax for that. So - that can be fine for a tiny personal project, or as a learning experience. But defining your own syntax for something so trivial and basic in a large project would be maintenance and readability hell.

2 Comments

I was trying to do this, but it wasn't working without the parenthesis
I guess the resulting expression is ambiguous without the brackets
10

You could do something like this:

10⨉{ print("loop") } 

Using a custom operator and an extension on Int:

infix operator ⨉ // multiplication sign, not lowercase 'x' extension Int { static func ⨉( count:Int, block: () ->Void ) { (0..<count).forEach { _ in block() } } } 

Comments

8

ABakerSmith's answer updated for Swift 4:

extension Int: Sequence { public func makeIterator() -> CountableRange<Int>.Iterator { return (0..<self).makeIterator() } } 

Use:

for i in 5 { //Performed 5 times } 

Comments

4

Shorter and (I think) clearer:

for i in 1...n { } // note: this will fail if n < 1 

or

for i in n { } 

2 Comments

for i in 1...n crashes for n = 0. So if this a valid input, make sure to use one of the other methods.
Well observed - comment added.
2

In Swift, what you have is the shortest syntax for performing a loop operation.

Swift provides two kinds of loop that perform a set of statements a certain number of times:

The for-in loop performs a set of statements for each item in a sequence.

The for loop performs a set of statements until a specific condition is met.

If you want to run it infinite times, well try using a while.

Comments

2

There are a lot of answers here, highlighting just how creative you can be, with Swift.

I needed an array so I did this

extension Int { func of<T>(iteration: (Int) -> T) -> [T] { var collection = [T]() for i in 0..<self { collection.append(iteration(i)) } return collection } } fun strings() -> [String] { return 4.of { "\($0) teletubby" } } 

Comments

0

for-loops are a common way to repeat code. Here is an example of using a for-loop to hide six outlets, versus writing the same code for six outlets. Plus if you make another outlet all you have to do is add it to the array.

let array = [outLet0, outlet1, outlet2, outLet3, outLet4, outLet5] for outlet in array { outlet.hidden = true } 

Versus writing it like this:

outlet0.hidden = true outlet1.hidden = true outlet2.hidden = true outlet3.hidden = true outlet4.hidden = true outlet5.hidden = true 

Comments

-1

Swift is so awesome, just write your own function or extension and you got it ;) 100 of options there, everyone can do it its own way just look at those answers here.

Or better, write it as you already do, as is common when apps are build in team, as everyone would do it differently anyway and all projects need those extension to be written again or own libs to have and maintain just for stupid thing, that you can write just by some standard way, as you already did with your for loop.

Comments

-2

ONLY 5 CHARACTERS (not including n or code)

r(){} 

If you're just testing things and need a REALLY short line, try this. Emphasis on using this for testing, not in production, because no one will know what is going on without documentation.

define this somewhere globally

func r(_ n : UInt, _ c: @escaping () -> Void) { for _ in 0..<n { c() } } 

call this when you want to run it

r(5) { /*code*/ } 

Comments

-4

The only loop shorter than that is an infinite while loop:

while (true) { } 

But you would still have to increase a counter and check it in the loop to break the loop, and in the end it wouldn't be shorter.

1 Comment

You even could shave a few more characters off by doing for ;; { } :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.