Который является лучшей практикой - для цикла с повреждением или условного цикла?

Вы должны действительно использовать $.each(). Предполагая, что у вас есть следующий HTML, я использовал правильные функции здесь, и вам даже не нужно закрытие в этом случае.

var $colors = $("#VARGRP1 > fieldset > label"); //the colored buttons
var $colorText = $(".colorVariantText"); //the span element to display the color text i.e: Red           

$colors.each(function () {
  $(this).css("background-color", $(this).data("variantcolor"));
  $colors.find("span").css("display", "none");
});
$colors.click( function () {
  $colorText.html($(this).attr("data-colorText")); 
});

Рабочий фрагмент

var $colors = $("#VARGRP1 > fieldset > label"); //the colored buttons
var $colorText = $(".colorVariantText"); //the span element to display the color text i.e: Red           

$colors.each(function () {
  $(this).css("background-color", $(this).data("variantcolor"));
  $colors.find("span").css("display", "none");
});
$colors.click( function () {
  $colorText.html($(this).attr("data-colorText")); 
});
<script src="https://code.jquery.com/jquery-2.2.4.js"></script>
<div id="VARGRP1">
  <fieldset>
    <label data-variantcolor="red" data-colorText="red">
      Click Me!
      <span></span>
    </label>
    <label data-variantcolor="green" data-colorText="green">
      Click Me!
      <span></span>
    </label>
    <label data-variantcolor="black" data-colorText="black">
      Click Me!
      <span></span>
    </label>
    <label data-variantcolor="blue" data-colorText="blue">
      Click Me!
      <span></span>
    </label>
    <label data-variantcolor="orange" data-colorText="orange">
      Click Me!
      <span></span>
    </label>
  </fieldset>
</div>
<div class="colorVariantText"></div>

26
задан Abdelilah El Aissaoui 29 August 2017 в 16:43
поделиться

18 ответов

Короче говоря, необходимо пойти с тем, какой бы ни версию является самым легким считать и поддержать.

В немного более старые времена, я знаю убегающий из цикла, считался нет - нет (наравне с оператором перехода). Циклы, как предполагалось, повреждались на условии цикла и больше нигде. Таким образом цикл с условием продолжения был бы способом пойти.

(Это - вероятно, пережиток от блока, где циклы являются в основном блоком кода с оператором перехода go-to-the-beginning-if-true в конце. Несколько операторов условного перехода в блоке делают его чрезвычайно трудно для отладки; таким образом их нужно было избежать и объединить в один в конце.)

я чувствую, что эта идея, кажется, изменяется немного сегодня, особенно с циклами foreach и управляемым миром; это - действительно вопрос стиля теперь. Break-found для циклов, возможно, стали приемлемыми для многих, сохраните некоторых пуристов, конечно. Обратите внимание, что я все еще избегал бы использования перерыва в цикле с условием продолжения, однако, поскольку это может запутать условие цикла и сделать его сбивающим с толку.

, Если Вы позволите мне использовать цикл foreach, я полагаю, что код ниже партия легче читать, чем ее брат цикла с условием продолжения:

bool isBaxterInMilwaukee;    

foreach (var item in myArray)
{
    if (item.name == "baxter" && item.location == "milwaukee")
    {
        isBaxterInMilwaukee = true;    
        barkTwice();
        break;
    }
}

Однако, поскольку логика растет в сложности, можно хотеть рассмотреть видный комментарий около break оператор, чтобы это не становится проложенным под землей и твердым найти.

<час>

Возможно, эта целая вещь должна быть пересмотрена в ее собственную функцию , который не делает break на найденном, но на самом деле return с результат (не стесняйтесь использовать версию для цикла вместо этого):

bool isBaxterInMilwaukee(Array myArray)
{      
    foreach (var item in myArray)
    {
        if (item.name == "baxter" && item.location == "milwaukee")
        {
            barkTwice();
            return true;
        }
    }
    return false;
}

, Поскольку Esko Luontola указал, вероятно, будет лучше переместить вызов в barkTwice() за пределами этой функции, поскольку побочный эффект не очевиден из имени функции, ни связанный с нахождением Baxter в каждом случае. (Или добавьте булев параметр BarkTwiceIfFound и измените строку для чтения if(BarkTwiceIfFound) barkTwice();, чтобы ясно дать понять побочный эффект.)

<час>

Для записи, можно также сделать, флаг регистрируется в для цикла без повреждения, но я чувствую, что это на самом деле повреждает удобочитаемость, потому что Вы не ожидаете дополнительного условия в определении для цикла:

var i:int;

var isBaxterInMilwaukee:Boolean;    

for (i = 0; !isBaxterInMilwaukee && i < arrayLen; i++)
{
    if (myArray[i]["name"] == "baxter"
         && myArray[i]["location"] == "milwaukee")
    {
        isBaxterInMilwaukee = true;    
        barkTwice();
    }
}

можно также моделировать механику автопостепенного увеличения с циклом с условием продолжения. Мне не нравится это по нескольким причинам - необходимо инициализировать i, чтобы быть тем меньше, чем реальное начальное значение, и в зависимости от того, как компилятор закорачивает логику условия цикла, значение [1 111] при выходе из цикла может варьироваться. Тем не менее, это возможно и для некоторых людей, это может улучшить удобочитаемость:

var i:int = -1;

var isBaxterInMilwaukee:Boolean;    

while (!isBaxterInMilwaukee && ++i < arrayLen)
{
    if (myArray[i]["name"] == "baxter"
         && myArray[i]["location"] == "milwaukee")
    {
        isBaxterInMilwaukee = true;
        barkTwice();
    }
}
31
ответ дан lc. 28 November 2019 в 06:25
поделиться

Я голосую while, потому что повреждения уменьшают grokability.

Вы не можете понять, что цикл содержит повреждение, если цикл стал слишком длинным, и Вы вводите код, который Вы ожидаете выполнять, и это не делает.

, Но я подписываюсь на не, заставляют меня думать модель о кодировании.

0
ответ дан Trampas Kirk 28 November 2019 в 06:25
поделиться

Моя общая позиция:

, Если это имеет использование счетчика цикла для () (как то, в то время как цикл с условием продолжения делает).

0
ответ дан cletus 28 November 2019 в 06:25
поделиться

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

Некоторый пример код C#:

class Program
{
   static bool IsBaxterInMilwaukee(IList<WhoAndWhere> peopleAndPlaces)
   {
      foreach (WhoAndWhere personAndPlace in peopleAndPlaces)
      {
         if (personAndPlace.Name == "Baxter" 
            && personAndPlace.Location == "Milwaukee")
         {
            return true;
         }
      }
      return false;
   }

   static void Main(string[] args)
   {
      List<WhoAndWhere> somePeopleAndPlaces = new List<WhoAndWhere>();
      somePeopleAndPlaces.Add(new WhoAndWhere("Fred", "Vancouver"));
      somePeopleAndPlaces.Add(new WhoAndWhere("Baxter", "Milwaukee"));
      somePeopleAndPlaces.Add(new WhoAndWhere("George", "London"));

      if (IsBaxterInMilwaukee(somePeopleAndPlaces))
      {
         // BarkTwice()
         Console.WriteLine("Bark twice");
      }
   }

   public class WhoAndWhere
   {
      public WhoAndWhere(string name, string location)
      {
         this.Name = name;
         this.Location = location;
      }

      public string Name { get; private set; }
      public string Location { get; private set; }
   }

}
1
ответ дан Wedge 28 November 2019 в 06:25
поделиться

Я предполагаю, что ни один не, на самом деле варьируются интересные. Необходимо искать высокоуровневые конструкции, если это - удобочитаемость, Вы после.

В JS:

if(myArray.some(function(o) { o.name == "baxter" && o.location == "milwaukee" }))
  barkTwice();

или с некоторым utils Вашего собственного

if(myArray.containsMatch({name:"baxter",location:"milwaukee"})
  barkTwice();
1
ответ дан John Nilsson 28 November 2019 в 06:25
поделиться

Моя теория состоит в том, что существует полезная абстракция программирования, подобная "отношению сигнал-шум", которое является "отношением проблемы к инструменту" - совершенство может измеряться в одном размере тем, сколько времени я провожу взгляды о проблеме и ее решении, по сравнению со временем, я трачу взгляды о том, как использовать инструмент (в этом синтаксисе языка случая).

той мерой, я пытаюсь использовать меньше конструкций более часто, потому что я (и надо надеяться те, кто следует) могу grok сущность моей структуры кода более быстро и точно. И так как изменения "для циклов" делают довольно хорошее задание покрытия случаев, где другие могли бы использоваться (без искажения), я использую их в качестве первого предпочтения, когда они являются взаимозаменяемыми.

И хорошо иметь все, что необходимо знать (grokwise) о правилах циклов в одной строке наверху "для" цикла. Я также склонен помещать переключатель "по умолчанию" сначала в тесты по той же причине.

, Но непротиворечивость и ясность ovveriding соображение. YMMV, конечно.

1
ответ дан dkretz 28 November 2019 в 06:25
поделиться

У меня есть фон C++ и таким образом, у меня все еще есть моменты, где я пытаюсь "думать как компилятор". Циклы с условием продолжения имеют тенденцию приводить к более трудному коду, и таким образом, для циклов только когда-либо рассматривались, если Вы знали, что собирались выполнить итерации по каждому элементу в массиве, каждый раз.

РЕДАКТИРОВАНИЕ: Я теперь полагаю, что это - излишество при использовании .NET или независимо от того, что Вы не собираетесь восполнять VM наверху с несколькими жесткими циклами. Я действительно думаю, помня, "почему" из определенных методов хорошая вещь все же.

1
ответ дан overslacked 28 November 2019 в 06:25
поделиться

Существует два аспекта проблемы:

  • , Что , чтобы сделать (например: найдите, содержит ли один из объектов указанного человека в месте)
  • Как , чтобы сделать это (например: используйте индекс, выполните итерации и т.д.)

, Оба из примеров смешивают два, и твердо понять что от как . Лучшее было бы то, если мы могли бы выразить в коде только что часть. Вот пример (c# 3.5), который делает это использование , шаблон спецификации

// what we are looking for?
IsPersonInLocation condition = new IsPersonInLocation("baxter", "milwaukee");

// does the array contain what we are looking for?
bool found = myArray.Find(item => condition.IsSatifiedBy(item));

// do something if the condition is satisfied
if (found) {
    barkTwice();
}

Для полноты вот является определением класса для условия:

class IsPersonInLocation {
    public string Person { get; set; }
    public string Location { get; set; }
    public IsPersonInLocation(string person, string location) {
        this.Person = person;
        this.Location = location;
    }
    bool IsSatifiedBy(item) {
        return item["name"] == this.Person
            && item["location"] == this.Location;
    }
}
2
ответ дан Aleris 28 November 2019 в 06:25
поделиться

Это во многом зависит от того, каковы определенные обстоятельства. Но в Вашем примере, Вы хотите обойти массив ограниченной длины, и использование для цикла помогает сделать это и принять меры против убегания конца. В Вашем примере цикла с условием продолжения необходимо сделать собственное постепенное увеличение - который может быть проблематичным, если Вы хотели использовать continue оператор, чтобы пропустить в следующий цикл - и сделать более сложное условное выражение (который, между прочим, имеет ошибку; я думаю, что Вы имели в виду && i != arrayLen). Необходимо просто сделать дополнительный код для выполнения эффекта, которые для циклов помогают обеспечить.

, Конечно, некоторые пуристы будут утверждать, что break и continue не должен использоваться и что необходимо использовать, если еще и логические переменные в случае необходимости, а не продолжаются или убегают из цикла. Но я думаю, что это может заставить цикл выглядеть намного более ужасным, особенно если его относительно короткое и легкое для схватывания в целом как этот пример. Для цикла с намного более длинным кодом, где повреждение или продолжаются, мог легко скрыться от уведомления, пуристский подход мог бы быть более четким, так как цикл является уже сложным для схватывания в этом случае. Но можно всегда делать это как часть для цикла, просто добавить его как часть условного выражения.

Это - также лучшая практика для тестирования массива, связанного с i < arrayLen, а не для точного равенства, в случае, если что-то заставило i перескакивать через точное значение (я на самом деле видел, что это произошло в относящейся к двухтысячному году ошибке, которой, возможно, избежала лучшая практика).

1
ответ дан Rob Parker 28 November 2019 в 06:25
поделиться

Я сказал бы, что повреждение, более ясное (даже если Вы вставляете комментарий, почему Вы убегаете из цикла), по моему скромному мнению, цикл с условием продолжения не ясен, я пошел бы для повреждения

2
ответ дан RvdK 28 November 2019 в 06:25
поделиться

повреждение считают "структурированным goto" и нужно использовать экономно. Используйте его, если это - меньшее из зла.

Избегают , продолжаются еще больше.

Редактирование: Так как я получил довольно много комментариев и некоторый downvotes, я добавлю некоторые ссылки поддержки

стандарт кодирования C/C++ А

И более слабый оператор для Java (см..52)

3
ответ дан Henk Holterman 28 November 2019 в 06:25
поделиться

Я вижу перерыв в обоих циклах, который корректен?

Так или иначе:

  • я выбрал бы цикл FOR, когда существует известное число (максимальное количество) повторений, прежде чем цикл запустится.
  • я выбрал бы WHILE иначе.
  • В ДЛЯ цикла я использую ПОВРЕЖДЕНИЕ свободно.
  • В Цикле с условием продолжения я предпочитаю использовать сложное условие вместо ПОВРЕЖДЕНИЯ (если это возможно).
3
ответ дан Jiri 28 November 2019 в 06:25
поделиться

Тот, который имеет большую часть смысла, будет тем, который передает идею человеку, читающему код лучшее. Помните удобочитаемость кода первый , и Вы будете обычно делать верный выбор. Обычно, Вы не хотите использовать что-то как break, если Вы действительно не должны, потому что это может сделать вещи трудно для следования, если делается часто или даже только в глубоко вложенном наборе выражений. continue может служить той же цели как повреждение иногда, и цикл будет тогда обычно выходить вместо того, потому что это было повреждено. В этом случае существует несколько различных способов, которыми я мог бы записать это.

, Вероятно, лучшей вещью, которую Вы хотите здесь, является модификация Вашего while цикл:

while(!isBaxterInMilwaukee || i < arrayLen) {
  if(myArray[i]["name"] == "baxter" && myArray[i]["location"] == "milwaukee") {
    isBaxterInMilwaukee == true;
    barkTwice()
  } else {
    i++;
  }
}

Это ясно и не использует break или continue, таким образом, можно сказать сразу, что Вы будете всегда завершать в результате одного из условий, определенных в while выражение.

ETA: Вероятно, должен быть i < arrayLen в while цикл иначе, он перестал работать в первый раз через, если входное значение не совпадает с целевым значением...

3
ответ дан Michael Trausch 28 November 2019 в 06:25
поделиться

Существует концептуальное различие между двумя. for циклы для итерации по дискретным наборам и while, циклы для повторения операторов на основе условия. Другие языки добавляют в finally пункты и конструкции цикличного выполнения как foreach или until. Они имеют тенденцию иметь значительно меньше традиционное for циклы.

В любом случае, правило, что я использую, состоит в том, что for циклы выполняют итерации и while повторение циклов. Если Вы видите что-то как:

while (counter <= end) {
   // do really cool stuff
   ++counter;
}

Тогда Вы, вероятно, более обеспечены с for цикл, так как Вы выполняете итерации. Однако циклы как:

for (int tryCount=0; tryCount<2; ++tryCount) {
    if (someOperation() == SUCCESS) {
       break;
    }
}

должен быть записан как [1 111] циклы, так как они действительно повторяют что-то, пока условие не верно.

мысль, не используя break, так как это столь же злое как goto , довольно бессмысленна. Как можно выровнять по ширине выдачу исключения тогда? Это - просто нелокальный и недетерминированный goto! Между прочим, это не напыщенная речь против обработки исключений, просто наблюдения.

4
ответ дан D.Shawley 28 November 2019 в 06:25
поделиться

В для цикла можно также рано выйти, вставив ранние критерии выхода для объявления цикла. Таким образом для Вашего примера Вы могли сделать это этот путь:

var i:int;

var isBaxterInMilwaukee:Boolean;    

isBaxterInMilwaukee = false;

for (i = 0; i < arrayLen && !isBaxterInMilwaukee; i++)
{
    if (myArray[i]["name"] == "baxter"
        && myArray[i]["location"] == "milwaukee")
    {
        isBaxterInMilwaukee = true;

        barkTwice();
    }
}

Тот способ, которым Вы не нуждаетесь в перерыве, и это еще более читаемо, чем некоторое время цикл.

4
ответ дан Joseph 28 November 2019 в 06:25
поделиться

Я сказал бы, что это зависит. В этом случае цикл с повреждением кажется более ясным мне.

5
ответ дан Ferruccio 28 November 2019 в 06:25
поделиться

Мне всегда не нравилось использование breaks в коде... В этом случае это, кажется, не имеет значения, но на более включенных циклах, это может ужасно сбивать с толку другой кодер, читающий его. В целом это часто приводит к не пониманию, как цикл может завершиться, пока кодер не определяет вложенный break глубоко в цикле. Путем определения условия флага это проверило каждое повторение цикла, оно делает это намного более ясным.

Эта проблема была бы подобна наличию return операторы, которые глубоки в теле метода, где они легко не определяются (а не переменная установки a retVal и возвращающийся в конце метода). С маленьким методом это кажется прекрасным, но чем больше это становится, тем более сбивающее с толку это будет.

Это не эффективность операционной вещи, это - вещь пригодности для обслуживания.

Спрашивают Ваших коллег, что читаемо и понятно для конкретной ситуации... Это - то, что действительно имеет значение.

8
ответ дан Andrew Flanagan 28 November 2019 в 06:25
поделиться

Я определенно пошел бы с for+break. ‘for’ является немедленно опознаваемой идиомой для “iterate по sequence”, и легче понять “iterate по последовательности; закончите рано если значение found”, чем объединенное условие цикла-и-остановки.

может быть доказательство для этого в способе, которым Вы, кажется, сделали две ошибки в своем условном коде цикла!

  • , в то время как условие (! isBaxterInMilwaukee || я == arrayLen),  —  did Вы означают “ (! (isBaxterInMilwaukee || я == arrayLen)) ”?

  • оператор завершения является ненужным при использовании оконечной переменной цикла.

Лично я нахожу, что простое ‘break’ намного более легкое читает, чем попытка отследить оконечную переменную цикла.

2
ответ дан bobince 28 November 2019 в 06:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: