@NinjaSystems

Как реализовать такую обработку CSV?

Пример исходного CSV файла выглядит так:
Продукт 1; Воздуховоды/Прямоугольные/Оцинкованные;
Продукт 2; Воздуховоды/Прямоугольные/Оцинкованные;
Продукт 3; Воздуховоды/Прямоугольные/Оцинкованные;
Продукт 4; Воздуховоды/Круглые/Нержавеющие;
Продукт 5; Воздуховоды/Круглые/Нержавеющие;
Продукт 6; Воздуховоды/Круглые/Нержавеющие;


Подскажите как обработать, чтобы получить такой результат?
Воздуховоды;
!Прямоугольные;
!!Оцинкованные;
Продукт 1; Воздуховоды/Прямоугольные/Оцинкованные;
Продукт 2; Воздуховоды/Прямоугольные/Оцинкованные;
Продукт 3; Воздуховоды/Прямоугольные/Оцинкованные;
!Круглые;
!!Нержавеющие;
Продукт 4; Воздуховоды/Круглые/Нержавеющие;
Продукт 5; Воздуховоды/Круглые/Нержавеющие;
Продукт 6; Воздуховоды/Круглые/Нержавеющие;


То есть с каждой следующей строки скрипт проверяет предыдущий массив и если категории различаются, то перед название продукта он добавляет категорию. Символ "!" означает уровень вложенной категории. В какой стороны подступиться подскажите.
  • Вопрос задан
  • 239 просмотров
Пригласить эксперта
Ответы на вопрос 2
@d-sem
Прочитать csv
Результат сгруппировать в ассоциативный массив по категориям сохраняя вложенность
Полученный ассоциативный массив обойти и записать в файл
Ответ написан
Fernus
@Fernus
Техник - Механик :)
Вот вариант, который будет работать при любом порядке категорий...
Оптимизировать/укоротить код - это уже Вам задание :)

<?php

$TEST_DATA = 'Продукт 1; Воздуховоды/Прямоугольные/Оцинкованные;
Продукт 2; Воздуховоды/Прямоугольные/Оцинкованные;
Продукт 3; Воздуховоды/Прямоугольные/Оцинкованные;
Продукт 4; Воздуховоды/Круглые/Нержавеющие;
Продукт 5; Воздуховоды/Круглые/Нержавеющие;
Продукт 6; Воздуховоды/Круглые/Нержавеющие;';

$TEST_DATA2 = 'Продукт 1; Воздуховоды/Прямоугольные/Оцинкованные;
Продукт 2; Воздуховоды/Круглые/Нержавеющие;
Продукт 3; Воздуховоды/Прямоугольные/Оцинкованные;
Продукт 4; Воздуховоды/Круглые/Нержавеющие;
Продукт 5; Воздуховоды/Прямоугольные/Оцинкованные;
Продукт 6; Воздуховоды/Круглые/Нержавеющие;';

$arData = array_map(function($val) {
    return array_filter(array_map('trim', explode(';', $val)));
}, preg_split('#[\r\n]#isu', $TEST_DATA, -1, PREG_SPLIT_NO_EMPTY));

/* Всё, что выше - к задаче не относится...имитация получения данных из CSV... */

$arRes = [];

foreach($arData as $data) {
    
    $arCategories = array_filter(array_map('trim', explode('/', $data[1])));
    
    $MAIN_CATEGORY = array_shift($arCategories);
    
    $HASH = md5(implode('/', $arCategories));
    
    $arRes[$MAIN_CATEGORY][$HASH][] = [
            'product_name' => $data[0],
            'category' => $data[1],
            'category_items' => $arCategories
        ];
    
}

$HASH = false;

foreach($arRes as $main_category => $arSubCategories) {
    
    echo $main_category."\r\n";
    
    foreach($arSubCategories as $h => $arItems)
        foreach($arItems as $item) {
            
            if($HASH != $h) {
                
                $HASH = $h;
                
                foreach($item['category_items'] as $k => $category) {
                
                    $k++;
                        
                    echo str_repeat('!', $k).$category."\r\n";
                
                }
                
            }
            
            echo $item['product_name'].';'.$item['category'].';'."\r\n";
            
        }
    
}

/* RESULT:

Воздуховоды
!Прямоугольные
!!Оцинкованные
Продукт 1;Воздуховоды/Прямоугольные/Оцинкованные;
Продукт 2;Воздуховоды/Прямоугольные/Оцинкованные;
Продукт 3;Воздуховоды/Прямоугольные/Оцинкованные;
!Круглые
!!Нержавеющие
Продукт 4;Воздуховоды/Круглые/Нержавеющие;
Продукт 5;Воздуховоды/Круглые/Нержавеющие;
Продукт 6;Воздуховоды/Круглые/Нержавеющие;

*/


UPD:
Вариант с одним циклом с учётом того, что категории уже отсортированы:
<?php

$TEST_DATA = 'Продукт 1; Воздуховоды/Прямоугольные/Оцинкованные;
Продукт 2; Воздуховоды/Прямоугольные/Оцинкованные;
Продукт 3; Воздуховоды/Прямоугольные/Оцинкованные;
Продукт 4; Воздуховоды/Круглые/Нержавеющие;
Продукт 5; Воздуховоды/Круглые/Нержавеющие;
Продукт 6; Воздуховоды/Круглые/Нержавеющие;';

$arData = array_map(function($val) {
    return array_filter(array_map('trim', explode(';', $val)));
}, preg_split('#[\r\n]#isu', $TEST_DATA, -1, PREG_SPLIT_NO_EMPTY));

/* Всё, что выше - к задаче не относится...имитация получения данных из CSV... */

$VAR = false;
$VAR2 = false;

foreach($arData as $data) {
    
    $arCategories = array_filter(array_map('trim', explode('/', $data[1])));
        
    $MAIN_CATEGORY = array_shift($arCategories);
    
    if($VAR !== $MAIN_CATEGORY) {
        
        $VAR = $MAIN_CATEGORY;
        
        echo $MAIN_CATEGORY."\r\n";
        
    }
    
    $CATEGORIES = implode('/', $arCategories);
    
    if($VAR2 !== $CATEGORIES) {
        
        foreach($arCategories as $k => $category) {
                
            $k++;
                
            echo str_repeat('!', $k).$category."\r\n";
                
        }
        
        $VAR2 = $CATEGORIES;
        
    }
    
    echo $data[0].';'.$data[1].';'."\r\n";

}

/* RESULT:

Воздуховоды
!Прямоугольные
!!Оцинкованные
Продукт 1;Воздуховоды/Прямоугольные/Оцинкованные;
Продукт 2;Воздуховоды/Прямоугольные/Оцинкованные;
Продукт 3;Воздуховоды/Прямоугольные/Оцинкованные;
!Круглые
!!Нержавеющие
Продукт 4;Воздуховоды/Круглые/Нержавеющие;
Продукт 5;Воздуховоды/Круглые/Нержавеющие;
Продукт 6;Воздуховоды/Круглые/Нержавеющие;

*/
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы