while ошибка цикла в сценарии оболочки [duplicate]

Это должно работать:

count(if(ccc_news_comments.id = 'approved', ccc_news_comments.id, NULL))

count() проверяет, существует ли это значение или нет. 0 эквивалентно существующему значению, поэтому он подсчитывает еще один, а NULL - как несуществующее значение, поэтому не учитывается.

12
задан Krumia 4 October 2016 в 09:52
поделиться

3 ответа

Используйте && / AND / and, а не || / OR / or:

v != "x" && v != "y" && v != "z"

Если параметр if всегда выполняется, условие для блока if всегда оценивается как true . Логическое выражение должно быть неверным.

Рассмотрим v != "x" || v != "y" || v != "z" для каждого значения v.

  • Когда v = "x", v != "x" становится "x" != "x" , который дает false . v != "y" становится "x" != "y", что дает true . v != "z" становится "x" != "y", что дает true . Выражение оценивается как false || true || true, которое является true .
  • Когда v = "y" выражение становится
    "y" != "x" || "y" != "y" || "y" != "z"
    
    или true || false || true, которое является истиной .
  • Когда v = "z" выражение становится
    "z" != "x" || "z" != "y" || "z" != "z"
    
    или true || true || false, которое является истиной .
  • Для любого другого значения для v выражение оценивается как true || true || true, которое является true .

В качестве альтернативы, рассмотрите правду -table:

       │     A          B          C      │
  v    │  v != "x"   v != "y"   v != "z"  │  A || B || C
───────┼──────────────────────────────────┼──────────────
 "x"   │    false      true       true    │     true
 "y"   │    true       false      true    │     true
 "z"   │    true       true       false   │     true
other  │    true       true       true    │     true

Как вы можете видеть, ваше логическое выражение всегда оценивается как true.

Что вы хотите сделать находим логическое выражение, которое оценивает true, когда

(v is not "x") and (v is not "y") and (v is not "z").

Правильная конструкция:

  • для C-подобных языков (например, , - (может потребоваться строгий оператор равенства !==), )
    if (v != "x" && v != "y" && v != "z")
    {
        // the statements I want to be executed
        // if v is neither "x", nor "y", nor "z"
    }
    
  • для паскальподобных языков
    IF (v != 'x' AND v != 'y' AND v != 'z') THEN
        -- the statements I want to be executed
        -- if v is neither "x", nor "y", nor "z"
    END IF;
    

В закон Моргана выражение также может быть переписано как (с использованием синтаксиса Си)

!(v == "x" || v == "y" || v == "z")

, что означает

not ((v is "x") or (v is "y") or (v is "z")).

Это делает логику более очевидной.


Некоторые языки имеют определенные конструкции для тестирования членства в наборах или y ou может использовать операции массива / списка.

18
ответ дан 9 revs, 3 users 47% 17 August 2018 в 12:06
поделиться

Вы можете использовать что-то вроде этого для PHP:

if(strpos('xyz',$v[0])===false)//example 1
//strpos returns false when the letter isn't in the string
//returns the position (0 based) of the substring
//we must use a strict comparison to see if it isn't in the substring

if(!in_array($v[0],array('x','y','z')))//example 2

//example 3
$out=array('x'=>1,'y'=>1,'z'=>1); //create an array
if(!$out[$v[0]]) //check if it's not 1

if(!preg_match('/^[xyz]$/',$v))//example 4, using regex

if(str_replace(array('x','y','z'),'',$v[0]))//example 5


if(trim($v[0],'xyz'))//example 6

Для Javascript:

if(~'xyz'.search(v[0]))//example 1(.indexOf() works too)

if(!(v[0] in {x:0,y:0,z:0}))//example 2

if(~['x','y','z'].indexOf(v[0]))//example 3, incompatible with older browsers.

if(!/^[xyz]$/.match(v))//example 4

if(v.replace(/^[xyz]$/))//example 5

Для MySQL:

Select not locate(@v,'xyz'); -- example 1

select @v not in ('x','y','z'); -- example 2

-- repetition of the same pattern for the others

Для C:

if(!strstr('xyz',v))//example 1, untested

Есть больше способов, я просто слишком ленив.

Используйте свое воображение и просто напишите то, что вам нравится больше!

2
ответ дан Ismael Miguel 17 August 2018 в 12:06
поделиться

Я полагал, что внес бы ответ на сценарий оболочки Bourne, поскольку синтаксис несколько свойственен.

В традиционном / POSIX sh тест равенства строк является особенностью команды [ (да, это отдельное имя команды!), у которого есть некоторые неприятные требования при цитировании и т. д.

#### WRONG
if [ "$v" != 'x' ] || [ "$v" != 'y'] || [ "$v" != 'z' ]; then
    : some code which should happen when $v is not 'x' or 'y' or 'z'
fi

Современные оболочки, такие как Ksh, Bash, Zsh и т. д., также имеют [[, что несколько менее надоедливо.

#### STILL WRONG
if [[ $v != 'x' || $v != 'y' || $v != 'z' ]]; then
    :  some code which should happen when $v is not 'x' or 'y' or 'z'
fi

Мы должны подчеркнуть требование наличия пробелов вокруг каждого токена, который пропускается многими новичками (т. е. вы не можете сказать if[[$v или $v!='y' без пробелов вокруг команд и операторов) , и кажущейся опциональности цитирования. Невозможность указать значение часто не является ошибкой синтаксиса , но это приведет к серьезным нежелательным семантическим проблемам, если вы не укажете значение, которое должно быть указано. ( Подробнее об этом в другом месте. )

Очевидное исправление здесь заключается в использовании && вместо ||, но вы также должны заметить, что [[ обычно поддерживает спорт для регулярных выражения, так что вы можете сказать что-то вроде

if [[ ! $v =~ ^(x|y|z)$ ]]; then
    : yeah
fi

и не забывайте о доверчивом старом case заявлении, которое вполне естественно для этого, и переносится обратно в конце 1970-х годов:

case $v in
    x | y | z)
       ;; # don't actually do anything in this switch
    *) # anything else, we fall through to this switch
       yeah
       some more yeah
       in fact, lots of yeah;;
 esac

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

(Это, очевидно, не подходит для оболочек Unix, которые не являются семейство Bourne. Семейство C-оболочек, в том числе еще несколько популярное tcsh, использует синтаксис, который предположительно «C-like», но это похоже на то, что он не может рассказать обо всем Элис Купер от девушки, которая отправилась в Страну Чудес; и у рыбы есть свои особенности, о которых я даже не могу комментировать.)

3
ответ дан tripleee 17 August 2018 в 12:06
поделиться
Другие вопросы по тегам:

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