Понимание петель - PullRequest
       7

Понимание петель

1 голос
/ 10 июня 2019

Как интерпретировать в циклах в Swift.

Я читаю код как

for score in individualscores (5 numbers total) 
if score (5) is greater than 4 
teamscore = 0 + 3

else 
teamscore = 0+1 

Фактический код Swift:

let individualScores = [75,43,103,87,12]

var teamScore  = 0

for score in individualScores {
    if score > 4 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
print(teamScore)

Результат возвращает 15, но я ожидал 5. Может кто-нибудь объяснить этот код?

Ответы [ 2 ]

1 голос
/ 11 июня 2019

Давайте используем «модель подстановки оценки», чтобы выяснить, что делает ваш цикл.

Вот цикл:

for score in individualScores {
    if score > 4 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}

Здесь individualScores означает значение, которое мы недавно присвоили свойству individualScores. Поэтому мы заменим упоминание individualScores значением individualScores:

for score in [75,43,103,87,12] {
    if score > 4 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}

Смысл цикла for-in состоит в том, чтобы назначить переменному первый элемент последовательности (поэтому установите score на 75) и выполнить тело цикла, а затем назначить второй элемент последовательности для переменной (поэтому установите score в 43) и выполните тело цикла, затем назначьте третий элемент последовательности переменной (так, установите score в 103) и выполните тело цикла и т. д.

Итак, давайте заменим цикл for-in на его значение:

do {
    let score = 75
    if score > 4 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
do {
    let score = 43
    if score > 4 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
do {
    let score = 103
    if score > 4 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
do {
    let score = 87
    if score > 4 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
do {
    let score = 12
    if score > 4 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}

Теперь мы можем упростить операторы if, подставив в каждый из них значения score:

do {
    if 75 > 4 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
do {
    if 43 > 4 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
do {
    if 103 > 4 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
do {
    if 87 > 4 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
do {
    if 12 > 4 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}

Далее мы упрощаем, оценивая условия:

do {
    if true {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
do {
    if true {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
do {
    if true {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
do {
    if true {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
do {
    if true {
        teamScore += 3
    } else {
        teamScore += 1
    }
}

Теперь, когда каждое условие if является простым true или false, мы можем значительно упростить замену каждого оператора if его последовательным (блок перед else) или его альтернативой. (блок после else) в зависимости от того, является ли условие true или false.

do {
    teamScore += 3
}
do {
    teamScore += 3
}
do {
    teamScore += 3
}
do {
    teamScore += 3
}
do {
    teamScore += 3
}

Поскольку мы удалили все операторы let, больше нет необходимости в операторах do, поэтому мы можем упростить их:

teamScore += 3
teamScore += 3
teamScore += 3
teamScore += 3
teamScore += 3

Эти пять утверждений имеют то же значение, что и это одно утверждение:

teamScore += 15

Так как teamScore был установлен в 0 в начале, он имеет значение 0 + 15 = 15 в конце.

1 голос
/ 11 июня 2019

Почему вы ожидали 5? Код работает как положено. В цикле For-in все объекты в последовательности (это может быть массив, словарь, диапазон, строка и т. Д.) Повторяются. Так как все они больше 4, ваш цикл выполняется 5 раз, а teamscore увеличивается на 3 в каждой итерации, что дает вам 15. Для перспективы измените код следующим образом:

let individualScores = [75,43,103,87,12]

var teamScore  = 0

for score in individualScores {
    print("Currently the value in score is: \(score)")
    if score > 4 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
print(teamScore)

Вы увидите следующие операторы печати:

Currently the value in score is: 75
Currently the value in score is: 43
Currently the value in score is: 103
Currently the value in score is: 87
Currently the value in score is: 12

Итак, сначала цикл не хранит счетчик, он просто использует длину массива. Он знает, что должен повторять 5 пунктов. Первый элемент 75, это больше 4, поэтому счет команды увеличивается на 3. Следующий элемент 43, тот же случай, что и 75. И так далее. Вот так и получается 15.

Ваша путаница, похоже, в том, что score будет иметь индекс каждого элемента, поэтому он будет идти 0,1,2,3,4. Поскольку ни один из этих значений не превышает 4, управление перестанет работать в другом состоянии и увеличится на teamscore на 1. Таким образом, вы пришли к выводу, что вы должны получить 5 в результате в teamscore. Сравнение того, что вы имели в виду, и того, как оно работает, будет следующим:

let individualScores = [75,43,103,87,12]

var teamScore  = 0
var indexScore = 0
for (index, score) in zip(individualScores.indices, individualScores) {
    print("Found \(score) at Index \(index)")

    //What you had in mind how it works
    if index > 4 {
        indexScore += 3
    } else {
        indexScore += 1
    }

    //How it actually works
    if score > 4 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
print("Team Score: \(teamScore)")
print("Index Score: \(indexScore)")

Теперь ваши печатные выписки будут:

Found 75 at Index 0
Found 43 at Index 1
Found 103 at Index 2
Found 87 at Index 3
Found 12 at Index 4
Team Score: 15
Index Score: 5

И индексный балл будет 5, как вы ожидали, но командный балл - 15.

Это потому, что for-in итерировал значения последовательностей, которые составляют 75,43,103,87 и 12, а не их индексы.

Кредиты для улучшения кода итерации: Робб Майофф и Александр

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...