Вложенный для каждого цикла через многомерный массив - как сделать условие для последнего значения

После катания на американских горках я «вот» близок к завершению сценария, над которым я работал.

У меня есть многомерный массив, хранящийся в $newarray, как показано ниже. Я сам построил этот массив, поэтому при необходимости код для его создания можно изменить. Но после создания я перебираю его, выбирая нужные мне значения. Я создаю новый массив для каждого ключа в верхнем массиве (в данном случае 3, 111, 222 и 333) и заполняю каждый набором объектов данных из следующего ключа массива вместе с некоторыми другими данными.

Однако в приведенном ниже случае мне нужно сгенерировать каждый из трех массивов (111, 222, 333) дважды, один раз, когда конечное значение массива = 0 ($ the_action), и один раз, когда оно = '1'. Где это = 1, напечатайте его, где это = 0, сделайте что-нибудь еще.

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

Благодарен за любую помощь.

Array
(
    [111] => Array
        (
            [1234] => Array
                (
                    [100000] => Array
                        (
                            [20000] => 0
                        )

                )

            [1244] => Array
                (
                    [100001] => Array
                        (
                            [20001] => 1
                        )

                )

            [1255] => Array
                (
                    [100002] => Array
                        (
                            [20002] => 1
                        )

                )

        )

    [222] => Array
        (
            [1233] => Array
                (
                    [100013] => Array
                        (
                            [20013] => 0
                        )

                )

            [1241] => Array
                (
                    [100014] => Array
                        (
                            [20014] => 1
                        )

                )

        )

    [333] => Array
        (
            [15633] => Array
                (
                    [100026] => Array
                        (
                            [20026] => 0
                        )

                )
            [12144] => Array
                (
                    [100028] => Array
                        (
                            [20028] => 0
                        )

                )

        )
)

Код для сборки $newarray ($stack взят из CSV с 5 столбцами):

$newarray = array();
foreach($stack as $val){
    $lineid = $val[0]; $segmentid = $val[1]; $action = $val[2]; $recency = $val[3]; $frequency = $val[4];
    $newarray[$lineid][$segmentid][$recency][$frequency] = $action;
}

Код для перебора массива:

foreach($newarray as $key => $value) {
    $target_pixels = array();
    $owner_id = $key;
    foreach($value as $key2 => $value2){
        $target_pixel = new stdClass;
        $target_pixel->conversion_id = $key2;
        $target_pixel->negated = false;
        foreach($value2 as $key3 => $value3){
            $target_pixel->seconds_since_conversion = $key3 * 24 * 60 * 60;
            foreach($value3 as $key4 => $value4){
                $target_pixel->frequency_min = $key4;
                $the_action = $value4;
            }
        }
        $target_pixels[] = $target_pixel;
    }
    print_r($target_pixels);
}

person Dan    schedule 08.06.2011    source источник
comment
Будет ли когда-либо у segmentid более одной давности и будет ли у давности более одной частоты? Если нет, то почти наверняка будет проще работать с такой структурой массива, как $array = array($lineid=>array($segmentid, $recency, $frequency));.   -  person Aether    schedule 08.06.2011
comment
Нет, они уникальны - существует соотношение 1:1:1 между идентификатором сегмента, частотой и давностью. Частота отображается как дочерний элемент новизны только из-за того, как собран массив. Он несовершенен, но после столь долгой работы с ним он работает (по крайней мере, до этого момента), и я поражен, что продвинулся так далеко.   -  person Dan    schedule 08.06.2011


Ответы (1)


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

$newarray = array();
foreach($stack as $val){
    $lineid = $val[0]; 
    $segmentid = $val[1]; 
    $action = $val[2]; 
    $recency = $val[3]; 
    $frequency = $val[4];
    $newarray[$lineid][$segmentid] = array(
        'recency' => $recency,
        'frequency' => $frequency
        'action' => $action
    );
}

Тогда ваш код будет выглядеть так:

foreach ($newarray as $lineid => $line) {
    $target_pixels = array();
    $owner_id = $lineid;
    foreach ($line as $segmentid => $segment){
        $target_pixel = new stdClass;
        $target_pixel->conversion_id = $segmentid;
        $target_pixel->negated = false;
        $target_pixel->seconds_since_conversion = $segment['recency'] * 24 * 60 * 60;
        $target_pixel->frequency_min = $segment['frequency'];

        $target_pixels[$segment['action']][] = $target_pixel;
    }
    var_dump($target_pixels);
}
person Aether    schedule 08.06.2011
comment
@Aether - var_dump - это удобно! Спасибо еще раз. Позвольте мне посмотреть, понимаю ли я новый код, который вы предлагаете. Что касается условного выражения, то я не понимаю, где разместить это условное выражение, потому что я не просто хочу что-то сделать для каждой из комбинаций segmentid/regency/частота, но (например, это может быть любое число) создайте 2 заполненных массива $target_pixels для каждого уникального $lineid - один, содержащий идентификаторы_сегментов, где действие = 0, и один, где действие = 1. Продолжить... - person Dan; 08.06.2011
comment
... В приведенном выше примере создаются 3 массива, каждый из которых содержит смесь 0 и 1, тогда как мне нужно 6 массивов, где печатаются 1, а с 0 я делаю что-то еще. Надеюсь, это имеет смысл? - person Dan; 08.06.2011
comment
@Dan Если вам все равно нужно выполнить оба действия для каждого массива, вы, вероятно, могли бы вообще отказаться от части action, а затем использовать один и тот же набор массивов для первого действия (печать) и второго действия (что бы это ни было). Если они должны быть отдельными (например, второе действие включает в себя манипулирование ими, но вы хотите, чтобы исходные данные были напечатаны позже), вы можете скопировать массивы и работать только с одной копией. - person Aether; 08.06.2011
comment
@Aether - Но каждое действие (0 и 1) необходимо выполнять только для соответствующих $segmentid. Возьмем, к примеру, массив 111 — нам нужно создать массив $target_pixels с двумя объектами данных target_pixel в нем (segmentid 1234 и 1244), затем что-то сделать, затем создать еще один массив target_pixels, на этот раз только с одним объектом данных target_pixel в нем. В пределах каждого линейного идентификатора действие должно быть выполнено с 0 как группой и с 1 как с группой, прежде чем переходить к следующему линейному идентификатору. Таким образом, кажется, что условное выражение будет после первого foreach и перед вторым, но я не понимаю, как это сделать. - person Dan; 08.06.2011
comment
@Dan - Ах, я думаю, это проясняет для меня! Я просто иногда немного медлительный. :) Давайте попробуем еще раз: я обновил свой ответ - теперь вы получаете два массива в массиве $target_pixels с индексами 0 и 1 - они соответствуют массивам с действием 0 и действием 1. Вы можете взять массив $target_pixels[0] и делать с ним что угодно это (действие 0), затем возьмите массив $target_pixels[1] и распечатайте его (действие 1). Это то, что вы ищете? - person Aether; 08.06.2011
comment
@Aether - Ты быстрее меня в свои медленные дни, так что не кори себя ;-). Это идеально и работает точно правильно и лучше, но я это понимаю. Спасибо большое! - person Dan; 08.06.2011
comment
@Dan - Рад помочь, и всегда лучше иметь понятный код! :) - person Aether; 08.06.2011