Tang
Tang

Reputation: 401

Swift, the for loop index value does not change as expectation

Here is my code, inside of my for loop, there is a while loop changes the variable i's value. I printed out the value of i before while loop and and after loop, the new "before index value" is expected to start at "after index value +1". However, the "new before index value" just increase as normal, which increase one each time. Appreciate your time.

class Solution
{
    func summaryRange(nums: [Int]) -> [String]
    {
        var result = [String]()

        if nums.count == 1
        {
            result.append(String(nums[0])+"")
            return result
        }

        for var i in (0...nums.count-1)
        {
            let a = nums[i]
            print("before: \(i)")

            while i+1<nums.count && (nums[i+1] - nums[i] == 1)
            {
                i += 1
            }

            if a != nums[i]
            {
                result.append(String(a) + "->" + String(nums[i]))
            }
            else
            {
                result.append(String(a)+"")
            }

            print("after: \(i)")

        }


        return result
    }
}



var test = Solution()
var input = [0,1,2,4,5,7]
var result = test.summaryRange(input)
print(result)

This code tries to get result like ["0->2","4->5","7"]

Upvotes: 1

Views: 2198

Answers (3)

kandelvijaya
kandelvijaya

Reputation: 1585

In swift, for in loop is a wrapper around the Sequence Type. In this particular case, 0...numCount-1 is a Sequence of Ints. When you call for in this is what happens internally.

    let a = 0..<5
    var generator = a.generate()
    while var i = generator.next() {
        print(i + 1)
        i+= 1
    }

So even if you increment the value of i inside the loop, it wont affect the loop itself. This is because loop is controller only by calling genertator.next().

This helps understand the basics.

Upvotes: 3

Tang
Tang

Reputation: 401

This is my own solution. I figure out the problem. Basically, I switch the "for loop" to a "while loop". Then, it works.

class Solution
{
    func summaryRanges(nums: [Int]) -> [String]
    {
        var result = [String]()

        var i = 0
        while(i<nums.count)
        {
            let a = nums[i]

            while i+1<nums.count && (nums[i+1] - nums[i] == 1)
            {
                i += 1
            }

            if a != nums[i]
            {
                result.append(String(a) + "->" + String(nums[i]))
            }
            else
            {
                result.append(String(a)+"")
            }
            i += 1


        }


        return result
    }
}

Upvotes: 2

DJohnson
DJohnson

Reputation: 919

This was an interesting one. I think this does the trick (with some code cleanup as well :-]

class Solution
{
  func summaryRange(nums: [Int]) -> [String] {
    var result = [String]()
    var currentRange = [Int]()

    for num in nums {
      if currentRange.isEmpty {                           //if range is empty, start a new range
        currentRange.append(num)
        continue
      }
      if num - 1 != currentRange.last! {                  //if not next number in sequence, close range, start new
        result.append(closeRange(currentRange))
        currentRange = []
        currentRange.append(num)
      } else if num - 1 == currentRange.last {
        currentRange.append(num)                          //if next number, add to range
      }
    }
    if !currentRange.isEmpty {
      result.append(closeRange(currentRange))            //check for unclosed ranges
    }
    return result
  }

  func closeRange(range: [Int]) -> String {
    guard range.count > 0 else { return "" }
    if range.count == 1 { return String(range.first!) }
    return "\(range.first!)->\(range.last!)"
  }
}

var test = Solution()
var input = [0,1,2,4,5,7]
var result = test.summaryRange(input)
print(result)

Let me know how this works for you!

Upvotes: 1

Related Questions