Сгруппируйте строки в одном столбце и сформируйте вложенный подмассив с другим столбцом

#php #arrays #grouping

Вопрос:

Вот с чем я пытаюсь разобраться, у меня есть массив, который выглядит так и имеет дубликаты

     $products = [
[
    "product_name" => "Adidas1",
    "address" => "street 2"
],
[
    "product_name" => "Adidas2",
    "address" => "street 2"
],
[
    "product_name" => "Adidas3",
    "address" => "street 2"
],
[
    "product_name" => "Adidas4",
    "address" => "street 2"
],
[
    "product_name" => "Nike1",
    "address" => "street name1"
],
[
    "product_name" => "Nike2",
    "address" => "street name1"
]];
 

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

 $final_result = [
[
    "address" => "street 2",
    "products" => [
        "addidas1",
        "addidas2",
        "addidas3",
        "addidas4",
        
    ]
],
[
    "address" => "street name1",
    "products" => [
        "Nike1",
        "Nike2",
       

    ]
]
 

есть какие-нибудь предложения, как это сделать ?

вот мое лучшее решение, которое я попробовал

 $stor_sorted = array();
foreach ($products as $product) {
    if (array_count_values($product) > 1) {
        $stor_sorted[] = ["address" => $product['address'], "items" => [$product['product_name']]];
    }
}
 

Ответ №1:

попробуйте этот код

 $products = [
        [
            "product_name" => "Adidas1",
            "address" => "street 2"
        ],
        [
            "product_name" => "Adidas2",
            "address" => "street 2"
        ],
        [
            "product_name" => "Adidas3",
            "address" => "street 2"
        ],
        [
            "product_name" => "Adidas4",
            "address" => "street 2"
        ],
        [
            "product_name" => "Nike1",
            "address" => "street name1"
        ],
        [
            "product_name" => "Nike2",
            "address" => "street name1"
        ]];

    $final_result = [];
    foreach ($products as $pr){
        $original_key = array_search($pr['address'], array_column($final_result, 'address'), true);
        if($original_key === false){
            $temp_array['address'] = $pr['address'];
            $temp_array['products'] =  [$pr['product_name']];
            $final_result[] =$temp_array;
        }else{
            $final_result[$original_key]['products'][] = $pr['product_name'];
        }
    }
 

ваш результат будет в массиве final_result

Комментарии:

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

Ответ №2:

Используйте address значения в качестве временных ключей в массиве результатов.

При первом обнаружении адреса приведите название продукта в виде массива в строке и сохраните строку.

При последующих встречах просто вставьте название продукта в подмассив группы.

Когда закончите, проиндексируйте результат с array_values() помощью .

Код: (Демо)

 $result = [];
foreach ($products as $row) {
    if (!isset($result[$row['address']])) {
        $row['product_name'] = (array)$row['product_name'];
        $result[$row['address']] = $row;
    } else {
        $result[$row['address']]['product_name'][] = $row['product_name'];
    }
}
var_export(array_values($result));
 

Комментарии:

1. @некоторые, почему вы приняли менее эффективный и необъяснимый ответ? Неужели вы не понимаете моего ответа?