Тернарный оператор с несколькими условиями, используемыми внутри массива в PHP

Если API дает следующий ответ, принимая во внимание array [0] и array [1], иногда может быть значение MX, а иногда может быть значение AR:

["published_sites"]=>
array(3) {
  [0]=>
  object(stdClass)#1565 (5) {
    ["site"]=>
    string(2) "MX"
    ["sale_price"]=>
    int(956)
    ["status"]=>
    string(6) "active"
    ["item_id"]=>
    string(12) "MLM724808"
    ["url"]=>
    string(108) "http://articulo.mercadolibre.com.mx/MLM-722808-apple-apple-watch-series-4-gps-cellular-44mm-space-bla-_JM"
  }
  [1]=>
  object(stdClass)#1569 (3) {
    ["site"]=>
    string(2) "AR"
        ["sale_price"]=>
        int(956)
        ["status"]=>
        string(6) "active"
        ["item_id"]=>
        string(12) "MLM724808"
        ["url"]=>
        string(108) "http://articulo.mercadolibre.com.ar/MLM-722808-apple-apple-watch-series-4-gps-cellular-44mm-space-bla-_JM"
}

и для сохранения в базе данных вы создаете массив со следующими полями для присвоения значений для AR и для MX:

    Channels::updateOrCreate(['mpid' => $response->mpid], [
    'mpid' => $response->mpid,
    'published_site_ar_item_id' => $assign item_id for AR, eg: $item_ar_assign
    'published_site_mx_item_id' => $assign item_id for MX,

Принимая во внимание, что Array может использовать только тернарный оператор для условных выражений, я пробовал использовать следующую структуру, но использование Or для нескольких условий не сработало. ->

item_ar_assign = ($response->published_sites['0']->site == 'AR' ?: $response->published_sites['0']->item_id)
                ||($response->published_sites['1']->site == 'AR' ?: $response->published_sites['1']->item_id)
            ||($response->published_sites['2']->site == 'AR' ? : $response->published_sites['2']->item_id)

Возможен ли этот подход тернарного оператора + несколько условий с массивами?

(примечание: я читал SO для дубликатов, таких как Тернарный оператор с несколькими условиями, но я не думаю такой же подход.)


person s_h    schedule 26.09.2019    source источник
comment
Почему вы используете === для вторых условий?   -  person Nawin    schedule 26.09.2019
comment
@Nawin, извините, опечатка. решено   -  person s_h    schedule 26.09.2019
comment
С ?: он либо вернет левую часть (что верно или неверно, как вы делаете == 'AR'), либо часть, следующую за : - вы имеете в виду $response->published_sites['0']->site == 'AR' ? 'AR': $response->published_sites['0']->item_id   -  person Nigel Ren    schedule 26.09.2019
comment
привет @NigelRen, моя идея состоит в том, чтобы вернуть строку $ response- ›published_sites ['0'] -› item_id, если массив ['0'] возвращает true, или $ response- ›published_sites ['1'] -› item_id, если массив ['1'] возвращает истину. Я не знаю, правильный ли это подход, но мне нужно условное выражение внутри массива и обязательно, если elseif, else не сработало. Спасибо!.   -  person s_h    schedule 26.09.2019


Ответы (1)


Во-первых, я не уверен, почему вы думаете, что здесь есть особая проблема с массивами. Подставим переменные, чтобы увидеть важную часть кода:

$site0 = $response->published_sites['0']->site;
$id0 = $response->published_sites['0']->item_id;

$site1 = $response->published_sites['1']->site;
$id1 = $response->published_sites['1']->item_id;

$site2 = $response->published_sites['2']->site;
$id2 = $response->published_sites['2']->item_id;

$item_ar_assign = 
    ($site0 == 'AR' ?: $id0)
    || ($site1 == 'AR' ?: $id1)
    || ($site2 == 'AR' ? : $id2);

Причина, по которой это не сработает, не связана с массивами, а потому, что вы использовали неправильные операторы:

  • Оператор PHP || всегда возвращает логическое значение - true или false, независимо от того, на какие значения он смотрит.
  • Форма $a ?: $b означает "$a, если это правда, или $b если нет". В этом случае $site0 == 'AR' ?: $id0 будет означать "true, если $site0 равно 'AR', или значение $id0, если нет"

Я думаю, вы пытаетесь вложить полную форму тернарного оператора $test ? $valueIfTrue : $valueIfFalse.

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

$item_ar_assign =
    ($site0 == 'AR') ? $id0
    : (
        $site1 == 'AR' ? $id1
        : (
            $site2 == 'AR' ? : $id2
        )
    );

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

if ($response->published_sites[0]->site == 'AR' ) {
    $item_ar_assign = $response->published_sites[0]->item_id;
}
elseif ($response->published_sites[1]->site == 'AR' ) {
    $item_ar_assign = $response->published_sites[1]->item_id;
}
elseif ($response->published_sites[2]->site == 'AR' ) {
    $item_ar_assign = $response->published_sites[2]->item_id;
}

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

foreach ( [0, 1, 2] as $site_number ) {
    if ($response->published_sites[$site_number]->site == 'AR' ) {
        $item_ar_assign = $response->published_sites[$site_number]->item_id;
        break; // stop at first match
    }
}

Или еще проще:

foreach ( $response->published_sites as $published_site ) {
    if ($published_site->site == 'AR' ) {
        $item_ar_assign = $published_site->item_id;
        break; // stop at first match
    }
}
person IMSoP    schedule 26.09.2019
comment
удивительно, поэтому моя проблема заключается в подходе, пытающемся объединить все в одни предложения, а не в чем-то более читаемом и понятном в первую очередь. Я попробую! - person s_h; 26.09.2019
comment
@s_h Пожалуйста, проверьте мою правку, чтобы получить еще более аккуратную версию :) - person IMSoP; 26.09.2019