Полагаю, это больше не актуально, но я застрял с тем же вопросом и нашел ответ.
Это можно сделать, используя только модуль npm glob
. Нам нужно использовать опций в качестве второго параметра функции glob
glob('pattern', {options}, cb)
Для ваших нужд существует шаблон options.ignore
.
var glob = require('glob');
glob("**/*",{"ignore":['index.html', 'js', 'js/app.js', 'js/lib.js']}, function (err, files) {
console.log(files);
})
Наверное. Человеческий мозг имеет ограниченное пространство стека, что затрудняет работу с глубоко вложенными структурами. Все, что сглаживает информацию, которую мы должны анализировать, упрощает ее понимание.
Точно так же я обычно предпочитаю это:
bool foo(int arg)
{
if(!arg) {
/* arg can't be 0 */
return false;
}
/* Do some work */
return true;
}
К этому:
bool foo(int arg)
{
if(!arg) {
/* arg can't be 0 */
return false;
} else {
/* Do some work */
return true;
}
}
Или, что еще хуже, к этому:
bool foo(int arg)
{
if(arg) {
/* Do some work */
return true;
} else {
/* arg can't be 0 */
return false;
}
}
В последнем примере, часть, которая выполняет эту работу, может быть довольно длинной. К тому времени, когда читатель дойдет до пункта else, он может не вспомнить, как он туда попал.
Помещение условий спасения как можно ближе к началу помогает гарантировать, что люди, которые попытаются вызвать ваши функции, будут иметь хорошее представление о какие входные данные ожидает функция.
Кроме того, как указывали другие, continue дает понять, что есть ' s нет необходимости углубляться в код внутри цикла, чтобы определить, выполняется ли какая-либо дополнительная обработка после этой точки для этого случая, что упрощает отслеживание кода. Опять же, чем меньше вещей вы заставляете читателя отслеживать, тем лучше.
Потому что с продолжением ясно, что код готов для этой итерации цикла. Если бы использовалось else, вам также нужно было проверить, нет ли кода после else.
Я думаю, что в целом хорошая привычка - как можно скорее выходить из контекста, потому что это приводит к гораздо более ясному коду.
] Например:
if(arg1 == NULL)
return;
if(arg2 == NULL)
return;
//Do some stuff
vs.
if(arg1 != null)
{
if(arg2 != null)
{
//Do some stuff
}
}
Я думаю, что у него было бы достаточно причин, чтобы сделать отступ для кода под переключателем, а создание отступа для всей функции функции является довольно расточительным по сравнению с горизонтальным пространством. В то время, когда был написан код, я полагаю, что 80 символов ширины все еще были популярны.
Я не думаю, что это сложно понять, но я действительно думаю, что было бы неплохо упомянуть, что вы НЕ делаете сразу, и затем GTFO.
Это намного легче читать, когда это написано вот так.
Мы закончили с этой итерацией цикла? Да? Итак, давайте продолжим со следующей итерации.
Всегда есть много способов написать такой код -
Помещение всего переключателя внутри оператора else было бы вполне допустимым. Я полагаю, что причина, по которой они сделали это таким образом ~ ~ ~ могла ~ быть именно тем, как они думали в то время:
«если значение в p не равно '%', положите, тогда продолжайте».
Если у вас есть переключатель под else, для автора может быть не так очевидно, что вы переходите к следующей итерации в этом конкретном случае.
Это полностью личный выбор стиля. Я бы не стал слишком беспокоиться - просто напишите это так, чтобы это было наиболее разумно для вас и вашей команды.
Согласен. Но вы не можете смотреть на это как на «простую причину», это на самом деле довольно веская причина, потому что она снижает общую сложность кода. Сделать его короче и легче читать и понимать.
Причин для продолжения / прерывания цикла может быть несколько. Так это будет выглядеть следующим образом:
loop
{
if (cond1)
{
if (cond2)
{
if (cond2)
{
more conditions...
}
}
}
else
{
the loop action
}
}
ИМХО, это не так элегантно и читабельно, как цикл в вашем примере, например:
loop
{
if (cond1)
continue;
if (cond2)
continue;
if (cond2)
continue;
if( more conditions...)
continue;
the loop action
}
И вам даже не нужно понимать всю структуру всех «if» (это может быть много более сложный), чтобы понять логику цикла.
PS на всякий случай: я не думаю, что авторы думали о том, как написать этот цикл, они просто написали его :)
Наиболее вероятная причина в том, что следующий за ним переключатель
довольно длинный - это похоже на синтаксический анализ формата printf
.
Если вы используете else
, тогда все, что находится внутри else
, требует с отступом:
if ()
{
doA();
}
else
{
doB();
if ()
{
doC();
}
else
{
doD()
}
}
Если вы используете continue
, вам не нужно делать отступ:
if ()
{
doA()
continue;
}
doB();
if ()
{
doC();
continue;
}
doD();
Кроме того, continue
означает, что я могу перестать думать об этом случае: например, если я увижу else
, то, возможно, будет больше обработки случая '%'
позже в цикле, то есть в конце оператора else
; тогда как, увидев continue
, я сразу понимаю, что обработка случая '%'
в цикле полностью завершена.
Я придерживаюсь учения Дейкстры: goto вредно . И continue / break - младшие братья goto.
Если проблема в том, что вы слишком сильно отступаете от кода, решение заключается не в добавлении продолжения в цикл, а в уменьшении сложности путем разделения кода на разные функции или мышления о том, как лучше организовать это.
Например, фрагмент @Kamarey был бы еще более ясным следующим образом:
loop
{
if (!(cond1 ||
cond2 ||
cond2 ||
...))
{
the loop actions;
}
}
или пример @Ori Pessach можно выразить так:
bool foo(int arg)
{
if(arg) {
/*do some work*/
}
return arg != 0;
}
Короче говоря, обычно я могу '
Ну, я писал программы на C около 11 лет, и мне пришлось 5 раз прочитать ваш фрагмент кода, чтобы понять его!
Керниган и Ричи были активны в шестидесятые годы. В то время способность понимать фрагмент кода не имела значения. Возможность писать код, который умещается в 16 Ko, была.
Так что я не удивлен. C - ужасный язык, когда ваши учителя - K&R. Посмотрите на realloc: кто бы мог знать код чего-то подобного сегодня? В 60-е это было в моде, но сейчас это ужасно, по крайней мере: o)